diff --git a/.gitlab/ci/opam-ci.yml b/.gitlab/ci/opam-ci.yml index b20e9103965ad0c2308d2e7d06b8ee3ec63246ef..b860b7234d3b95d6c25eec5bf4385878cc6962c7 100644 --- a/.gitlab/ci/opam-ci.yml +++ b/.gitlab/ci/opam-ci.yml @@ -328,20 +328,6 @@ opam:octez-protocol-compiler: variables: package: octez-protocol-compiler -opam:octez-sc-rollup-client-PtKathma: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_2 - variables: - package: octez-sc-rollup-client-PtKathma - -opam:octez-sc-rollup-client-PtLimaPt: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_2 - variables: - package: octez-sc-rollup-client-PtLimaPt - opam:octez-sc-rollup-client-alpha: extends: - .opam_template @@ -349,20 +335,6 @@ opam:octez-sc-rollup-client-alpha: variables: package: octez-sc-rollup-client-alpha -opam:octez-sc-rollup-node-PtKathma: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_1 - variables: - package: octez-sc-rollup-node-PtKathma - -opam:octez-sc-rollup-node-PtLimaPt: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_1 - variables: - package: octez-sc-rollup-node-PtLimaPt - opam:octez-sc-rollup-node-alpha: extends: - .opam_template @@ -492,7 +464,7 @@ opam:tezos-baking-alpha-commands: opam:tezos-base: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-base @@ -555,7 +527,7 @@ opam:tezos-benchmark-type-inference-015-PtLimaPt: opam:tezos-benchmark-type-inference-alpha: extends: - .opam_template - - .rules_template__trigger_opam_batch_2 + - .rules_template__trigger_opam_batch_1 variables: package: tezos-benchmark-type-inference-alpha @@ -583,7 +555,7 @@ opam:tezos-benchmarks-proto-alpha: opam:tezos-clic: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-clic @@ -702,14 +674,14 @@ opam:tezos-client-015-PtLimaPt: opam:tezos-client-alpha: extends: - .opam_template - - .rules_template__trigger_opam_batch_3 + - .rules_template__trigger_opam_batch_2 variables: package: tezos-client-alpha opam:tezos-client-base: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-client-base @@ -758,28 +730,21 @@ opam:tezos-context-ops: opam:tezos-crypto: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-crypto opam:tezos-crypto-dal: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-crypto-dal -opam:tezos-dal-015-PtLimaPt: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_2 - variables: - package: tezos-dal-015-PtLimaPt - opam:tezos-dal-alpha: extends: - .opam_template - - .rules_template__trigger_opam_batch_2 + - .rules_template__trigger_opam_batch_1 variables: package: tezos-dal-alpha @@ -807,42 +772,42 @@ opam:tezos-embedded-protocol-002-PsYLVpVv: opam:tezos-embedded-protocol-003-PsddFKi3: extends: - .opam_template - - .rules_template__trigger_opam_batch_4 + - .rules_template__trigger_opam_batch_3 variables: package: tezos-embedded-protocol-003-PsddFKi3 opam:tezos-embedded-protocol-004-Pt24m4xi: extends: - .opam_template - - .rules_template__trigger_opam_batch_4 + - .rules_template__trigger_opam_batch_3 variables: package: tezos-embedded-protocol-004-Pt24m4xi opam:tezos-embedded-protocol-005-PsBABY5H: extends: - .opam_template - - .rules_template__trigger_opam_batch_4 + - .rules_template__trigger_opam_batch_3 variables: package: tezos-embedded-protocol-005-PsBABY5H opam:tezos-embedded-protocol-005-PsBabyM1: extends: - .opam_template - - .rules_template__trigger_opam_batch_4 + - .rules_template__trigger_opam_batch_3 variables: package: tezos-embedded-protocol-005-PsBabyM1 opam:tezos-embedded-protocol-006-PsCARTHA: extends: - .opam_template - - .rules_template__trigger_opam_batch_4 + - .rules_template__trigger_opam_batch_3 variables: package: tezos-embedded-protocol-006-PsCARTHA opam:tezos-embedded-protocol-007-PsDELPH1: extends: - .opam_template - - .rules_template__trigger_opam_batch_4 + - .rules_template__trigger_opam_batch_3 variables: package: tezos-embedded-protocol-007-PsDELPH1 @@ -947,14 +912,14 @@ opam:tezos-error-monad: opam:tezos-event-logging: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-event-logging opam:tezos-event-logging-test-helpers: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-event-logging-test-helpers @@ -968,7 +933,7 @@ opam:tezos-expect-helper: opam:tezos-hacl: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-hacl @@ -1000,13 +965,6 @@ opam:tezos-injector-alpha: variables: package: tezos-injector-alpha -opam:tezos-layer2-utils-015-PtLimaPt: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_2 - variables: - package: tezos-layer2-utils-015-PtLimaPt - opam:tezos-layer2-utils-alpha: extends: - .opam_template @@ -1213,42 +1171,42 @@ opam:tezos-protocol-014-PtKathma: opam:tezos-protocol-015-PtLimaPt: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-protocol-015-PtLimaPt opam:tezos-protocol-alpha: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-protocol-alpha opam:tezos-protocol-demo-counter: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-protocol-demo-counter opam:tezos-protocol-demo-noops: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-protocol-demo-noops opam:tezos-protocol-environment: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-protocol-environment opam:tezos-protocol-genesis: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-protocol-genesis @@ -1262,7 +1220,7 @@ opam:tezos-protocol-plugin-007-PsDELPH1: opam:tezos-protocol-plugin-007-PsDELPH1-registerer: extends: - .opam_template - - .rules_template__trigger_opam_batch_3 + - .rules_template__trigger_opam_batch_2 variables: package: tezos-protocol-plugin-007-PsDELPH1-registerer @@ -1276,7 +1234,7 @@ opam:tezos-protocol-plugin-008-PtEdo2Zk: opam:tezos-protocol-plugin-008-PtEdo2Zk-registerer: extends: - .opam_template - - .rules_template__trigger_opam_batch_3 + - .rules_template__trigger_opam_batch_2 variables: package: tezos-protocol-plugin-008-PtEdo2Zk-registerer @@ -1290,7 +1248,7 @@ opam:tezos-protocol-plugin-009-PsFLoren: opam:tezos-protocol-plugin-009-PsFLoren-registerer: extends: - .opam_template - - .rules_template__trigger_opam_batch_3 + - .rules_template__trigger_opam_batch_2 variables: package: tezos-protocol-plugin-009-PsFLoren-registerer @@ -1304,28 +1262,28 @@ opam:tezos-protocol-plugin-010-PtGRANAD: opam:tezos-protocol-plugin-010-PtGRANAD-registerer: extends: - .opam_template - - .rules_template__trigger_opam_batch_3 + - .rules_template__trigger_opam_batch_2 variables: package: tezos-protocol-plugin-010-PtGRANAD-registerer opam:tezos-protocol-plugin-011-PtHangz2: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-protocol-plugin-011-PtHangz2 opam:tezos-protocol-plugin-011-PtHangz2-registerer: extends: - .opam_template - - .rules_template__trigger_opam_batch_3 + - .rules_template__trigger_opam_batch_2 variables: package: tezos-protocol-plugin-011-PtHangz2-registerer opam:tezos-protocol-plugin-012-Psithaca: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-protocol-plugin-012-Psithaca @@ -1339,7 +1297,7 @@ opam:tezos-protocol-plugin-012-Psithaca-registerer: opam:tezos-protocol-plugin-013-PtJakart: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-protocol-plugin-013-PtJakart @@ -1353,7 +1311,7 @@ opam:tezos-protocol-plugin-013-PtJakart-registerer: opam:tezos-protocol-plugin-014-PtKathma: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-protocol-plugin-014-PtKathma @@ -1367,7 +1325,7 @@ opam:tezos-protocol-plugin-014-PtKathma-registerer: opam:tezos-protocol-plugin-015-PtLimaPt: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-protocol-plugin-015-PtLimaPt @@ -1381,7 +1339,7 @@ opam:tezos-protocol-plugin-015-PtLimaPt-registerer: opam:tezos-protocol-plugin-alpha: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-protocol-plugin-alpha @@ -1395,14 +1353,14 @@ opam:tezos-protocol-plugin-alpha-registerer: opam:tezos-protocol-updater: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-protocol-updater opam:tezos-proxy: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-proxy @@ -1462,27 +1420,6 @@ opam:tezos-sapling: variables: package: tezos-sapling -opam:tezos-sc-rollup-013-PtJakart: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_4 - variables: - package: tezos-sc-rollup-013-PtJakart - -opam:tezos-sc-rollup-014-PtKathma: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_4 - variables: - package: tezos-sc-rollup-014-PtKathma - -opam:tezos-sc-rollup-015-PtLimaPt: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_4 - variables: - package: tezos-sc-rollup-015-PtLimaPt - opam:tezos-sc-rollup-alpha: extends: - .opam_template @@ -1507,14 +1444,14 @@ opam:tezos-shell: opam:tezos-shell-benchmarks: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-shell-benchmarks opam:tezos-shell-context: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-shell-context @@ -1542,7 +1479,7 @@ opam:tezos-signer-backends: opam:tezos-signer-services: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-signer-services @@ -1556,7 +1493,7 @@ opam:tezos-stdlib: opam:tezos-stdlib-unix: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-stdlib-unix @@ -1640,7 +1577,7 @@ opam:tezos-webassembly-interpreter: opam:tezos-webassembly-interpreter-extra: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-webassembly-interpreter-extra diff --git a/dune-project b/dune-project index 943f80e34e3b949e0dcbe8d578560c4e2b8bf3d5..c7ebb8021228e1397bdca0ca8ae27ad0400c196b 100644 --- a/dune-project +++ b/dune-project @@ -15,11 +15,7 @@ (package (name octez-node)) (package (name octez-protocol-compiler)) (package (name octez-proxy-server)) -(package (name octez-sc-rollup-client-PtKathma)) -(package (name octez-sc-rollup-client-PtLimaPt)) (package (name octez-sc-rollup-client-alpha)) -(package (name octez-sc-rollup-node-PtKathma)) -(package (name octez-sc-rollup-node-PtLimaPt)) (package (name octez-sc-rollup-node-alpha)) (package (name octez-signer)) (package (name octez-snoop)) @@ -80,7 +76,6 @@ (package (name tezos-context-ops)) (package (name tezos-crypto)) (package (name tezos-crypto-dal)) -(package (name tezos-dal-015-PtLimaPt)) (package (name tezos-dal-alpha)) (package (name tezos-dal-node-lib)(allow_empty)) (package (name tezos-dal-node-services)(allow_empty)) @@ -116,7 +111,6 @@ (package (name tezos-injector-015-PtLimaPt)) (package (name tezos-injector-alpha)) (package (name tezos-layer2-store)(allow_empty)) -(package (name tezos-layer2-utils-015-PtLimaPt)) (package (name tezos-layer2-utils-alpha)) (package (name tezos-lazy-containers)) (package (name tezos-lazy-containers-tests)(allow_empty)) @@ -189,9 +183,6 @@ (package (name tezos-rpc-http-client-unix)) (package (name tezos-rpc-http-server)) (package (name tezos-sapling)) -(package (name tezos-sc-rollup-013-PtJakart)) -(package (name tezos-sc-rollup-014-PtKathma)) -(package (name tezos-sc-rollup-015-PtLimaPt)) (package (name tezos-sc-rollup-alpha)) (package (name tezos-scoru-wasm)) (package (name tezos-scoru-wasm-test)(allow_empty)) diff --git a/manifest/main.ml b/manifest/main.ml index b18edd1fc270321702a9f0dbaa59628514568455..650c9323551db33daa5e699d1175b058334da088 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -3591,7 +3591,7 @@ end = struct (2, "test_sc_rollup_tick_repr", N.(number >= 013)); (2, "test_sc_rollup_encoding", N.(number >= 015)); (3, "refutation_game_pbt", N.(number == 013)); - (3, "test_refutation_game", N.(number >= 014)); + (3, "test_refutation_game", N.(number >= 016)); (3, "test_carbonated_map", N.(number >= 013)); (3, "test_zk_rollup_encoding", N.(number >= 015)); (3, "test_dal_slot_proof", N.(number >= 016)); @@ -3634,7 +3634,7 @@ end = struct octez_benchmark; benchmark |> if_some |> open_; benchmark_type_inference |> if_some |> open_; - sc_rollup |> if_some |> if_ N.(number >= 015) |> open_; + sc_rollup |> if_some |> if_ N.(number >= 016) |> open_; octez_crypto_dal |> if_ N.(number >= 016) |> open_; octez_base_test_helpers |> if_ N.(number >= 016) |> open_; ] @@ -4567,7 +4567,7 @@ module Protocol = Protocol ~linkall:true in let layer2_utils = - only_if N.(number >= 015) @@ fun () -> + only_if N.(number >= 016) @@ fun () -> public_lib (sf "tezos-layer2-utils-%s" name_dash) ~path:(path // "lib_layer2_utils") @@ -4583,7 +4583,7 @@ module Protocol = Protocol ~linkall:true in let sc_rollup = - only_if N.(number >= 013) @@ fun () -> + only_if N.(number >= 016) @@ fun () -> public_lib (sf "tezos-sc-rollup-%s" name_dash) ~path:(path // "lib_sc_rollup") @@ -4601,7 +4601,7 @@ module Protocol = Protocol ~linkall:true in let _sc_rollup_client = - only_if (active && N.(number >= 013)) @@ fun () -> + only_if (active && N.(number >= 016)) @@ fun () -> public_exe (sf "octez-sc-rollup-client-%s" short_hash) ~internal_name:(sf "main_sc_rollup_client_%s" name_underscore) @@ -4626,7 +4626,7 @@ module Protocol = Protocol ] in let _sc_rollup_node = - only_if (active && N.(number >= 013)) @@ fun () -> + only_if (active && N.(number >= 016)) @@ fun () -> public_exe (sf "octez-sc-rollup-node-%s" short_hash) ~internal_name:(sf "main_sc_rollup_node_%s" name_underscore) @@ -4746,7 +4746,7 @@ module Protocol = Protocol ] in let dal = - only_if (active && N.(number >= 015)) @@ fun () -> + only_if (active && N.(number >= 016)) @@ fun () -> public_lib (sf "tezos-dal-%s" name_dash) ~path:(path // "lib_dal") @@ -4768,7 +4768,7 @@ module Protocol = Protocol ~linkall:true in let _dal_tests = - only_if (active && N.(number >= 015)) @@ fun () -> + only_if (active && N.(number >= 016)) @@ fun () -> test "main" ~path:(path // "lib_dal/test") diff --git a/opam/octez-dal-node.opam b/opam/octez-dal-node.opam index dd52abd5aea70d901693b47d38255b89807d1d04..25b42e73d19be78c871ff1fcd8b2b48aab99086c 100644 --- a/opam/octez-dal-node.opam +++ b/opam/octez-dal-node.opam @@ -26,7 +26,6 @@ depends: [ "tezos-crypto-dal" "irmin-pack" { >= "3.4.0" & < "3.5.0" } "irmin" { >= "3.4.0" & < "3.5.0" } - "tezos-dal-015-PtLimaPt" ] depopts: [ "tezos-dal-alpha" diff --git a/opam/octez-sc-rollup-client-PtKathma.opam b/opam/octez-sc-rollup-client-PtKathma.opam deleted file mode 100644 index cd834a0cb12bfbeb40107598a4b97b9e1f180665..0000000000000000000000000000000000000000 --- a/opam/octez-sc-rollup-client-PtKathma.opam +++ /dev/null @@ -1,30 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -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" { >= "3.0" } - "tezos-base" - "tezos-clic" - "tezos-client-base" - "tezos-client-014-PtKathma" - "tezos-client-commands" - "tezos-stdlib-unix" - "tezos-client-base-unix" - "tezos-rpc-http" - "tezos-rpc-http-client-unix" - "tezos-protocol-014-PtKathma" - "tezos-sc-rollup-014-PtKathma" - "uri" { >= "2.2.0" } -] -build: [ - ["rm" "-r" "vendors"] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: `octez-sc-rollup-client-alpha` client binary" diff --git a/opam/octez-sc-rollup-client-PtLimaPt.opam b/opam/octez-sc-rollup-client-PtLimaPt.opam deleted file mode 100644 index 368039bfe080cccf78c5195a20782f6f64fcc490..0000000000000000000000000000000000000000 --- a/opam/octez-sc-rollup-client-PtLimaPt.opam +++ /dev/null @@ -1,30 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -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" { >= "3.0" } - "tezos-base" - "tezos-clic" - "tezos-client-base" - "tezos-client-015-PtLimaPt" - "tezos-client-commands" - "tezos-stdlib-unix" - "tezos-client-base-unix" - "tezos-rpc-http" - "tezos-rpc-http-client-unix" - "tezos-protocol-015-PtLimaPt" - "tezos-sc-rollup-015-PtLimaPt" - "uri" { >= "2.2.0" } -] -build: [ - ["rm" "-r" "vendors"] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: `octez-sc-rollup-client-alpha` client binary" diff --git a/opam/octez-sc-rollup-node-PtKathma.opam b/opam/octez-sc-rollup-node-PtKathma.opam deleted file mode 100644 index afe29f495efb0d39dc46b9a289eb7eb9033f1098..0000000000000000000000000000000000000000 --- a/opam/octez-sc-rollup-node-PtKathma.opam +++ /dev/null @@ -1,42 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -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" { >= "3.0" } - "tezos-base" - "tezos-clic" - "tezos-client-commands" - "tezos-stdlib-unix" - "tezos-client-base" - "tezos-client-base-unix" - "tezos-client-014-PtKathma" - "tezos-context" - "tezos-protocol-014-PtKathma" - "tezos-protocol-plugin-014-PtKathma" - "tezos-rpc" - "tezos-rpc-http" - "tezos-rpc-http-server" - "tezos-dal-node-services" - "tezos-shell-services" - "tezos-sc-rollup-014-PtKathma" - "tezos-layer2-store" - "data-encoding" { >= "0.6" & < "0.7" } - "irmin-pack" { >= "3.4.0" & < "3.5.0" } - "irmin" { >= "3.4.0" & < "3.5.0" } - "ringo" { >= "0.9" } - "ringo-lwt" { >= "0.9" } - "tezos-injector-014-PtKathma" - "tezos-scoru-wasm" -] -build: [ - ["rm" "-r" "vendors"] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: Smart Contract Rollup node binary" diff --git a/opam/octez-sc-rollup-node-PtLimaPt.opam b/opam/octez-sc-rollup-node-PtLimaPt.opam deleted file mode 100644 index f6ba2b58ac67925bda3a47de58a199c2f28c4c5e..0000000000000000000000000000000000000000 --- a/opam/octez-sc-rollup-node-PtLimaPt.opam +++ /dev/null @@ -1,43 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -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" { >= "3.0" } - "tezos-base" - "tezos-clic" - "tezos-client-commands" - "tezos-stdlib-unix" - "tezos-client-base" - "tezos-client-base-unix" - "tezos-client-015-PtLimaPt" - "tezos-context" - "tezos-protocol-015-PtLimaPt" - "tezos-protocol-plugin-015-PtLimaPt" - "tezos-rpc" - "tezos-rpc-http" - "tezos-rpc-http-server" - "tezos-dal-node-services" - "tezos-shell-services" - "tezos-sc-rollup-015-PtLimaPt" - "tezos-layer2-utils-015-PtLimaPt" - "tezos-layer2-store" - "data-encoding" { >= "0.6" & < "0.7" } - "irmin-pack" { >= "3.4.0" & < "3.5.0" } - "irmin" { >= "3.4.0" & < "3.5.0" } - "ringo" { >= "0.9" } - "ringo-lwt" { >= "0.9" } - "tezos-injector-015-PtLimaPt" - "tezos-scoru-wasm" -] -build: [ - ["rm" "-r" "vendors"] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: Smart Contract Rollup node binary" diff --git a/opam/tezos-dal-015-PtLimaPt.opam b/opam/tezos-dal-015-PtLimaPt.opam deleted file mode 100644 index e5795b58996f4cd56926c3f6aa9f45223e6415ac..0000000000000000000000000000000000000000 --- a/opam/tezos-dal-015-PtLimaPt.opam +++ /dev/null @@ -1,29 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -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" { >= "3.0" } - "ppx_expect" - "tezos-base" - "octez-protocol-compiler" - "tezos-dal-node-lib" - "tezos-client-015-PtLimaPt" - "tezos-embedded-protocol-015-PtLimaPt" - "tezos-layer2-utils-015-PtLimaPt" - "tezos-protocol-015-PtLimaPt" - "tezos-base-test-helpers" {with-test} - "tezos-015-PtLimaPt-test-helpers" {with-test} - "alcotest-lwt" { with-test & >= "1.5.0" } -] -build: [ - ["rm" "-r" "vendors"] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol specific library for the Data availability Layer" diff --git a/opam/tezos-layer2-utils-015-PtLimaPt.opam b/opam/tezos-layer2-utils-015-PtLimaPt.opam deleted file mode 100644 index 0adec67b4622354d7eedeb2a64f2e6d3a38e38e7..0000000000000000000000000000000000000000 --- a/opam/tezos-layer2-utils-015-PtLimaPt.opam +++ /dev/null @@ -1,23 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -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" { >= "3.0" } - "ppx_expect" - "tezos-base" - "tezos-protocol-015-PtLimaPt" - "tezos-client-015-PtLimaPt" - "tezos-rpc" -] -build: [ - ["rm" "-r" "vendors"] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol specific library for Layer 2 utils" diff --git a/opam/tezos-protocol-015-PtLimaPt-tests.opam b/opam/tezos-protocol-015-PtLimaPt-tests.opam index 2f976f11f9a25b53ffdf12f333d2a1659c8526bd..da3ce07382dff3aaad2e8c58715e8e8409378fb1 100644 --- a/opam/tezos-protocol-015-PtLimaPt-tests.opam +++ b/opam/tezos-protocol-015-PtLimaPt-tests.opam @@ -25,7 +25,6 @@ depends: [ "tezos-context" {with-test} "tezos-test-helpers" {with-test} "alcotest" { with-test & >= "1.5.0" } - "tezos-sc-rollup-015-PtLimaPt" {with-test} "tezos-client-base" {with-test} "tezos-protocol-environment" {with-test} "tezos-stdlib-unix" {with-test} diff --git a/opam/tezos-sc-rollup-013-PtJakart.opam b/opam/tezos-sc-rollup-013-PtJakart.opam deleted file mode 100644 index 4f2c18e0790937626326c095c8fbbf153c59f94b..0000000000000000000000000000000000000000 --- a/opam/tezos-sc-rollup-013-PtJakart.opam +++ /dev/null @@ -1,23 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -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" { >= "3.0" } - "ppx_expect" - "tezos-base" - "tezos-protocol-013-PtJakart" - "tezos-protocol-plugin-013-PtJakart" - "tezos-rpc" -] -build: [ - ["rm" "-r" "vendors"] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol specific library for `tezos-sc-rollup`" diff --git a/opam/tezos-sc-rollup-014-PtKathma.opam b/opam/tezos-sc-rollup-014-PtKathma.opam deleted file mode 100644 index a043a24881e4e4bb2068f4de69273d30381a33c6..0000000000000000000000000000000000000000 --- a/opam/tezos-sc-rollup-014-PtKathma.opam +++ /dev/null @@ -1,23 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -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" { >= "3.0" } - "ppx_expect" - "tezos-base" - "tezos-protocol-014-PtKathma" - "tezos-protocol-plugin-014-PtKathma" - "tezos-rpc" -] -build: [ - ["rm" "-r" "vendors"] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol specific library for `tezos-sc-rollup`" diff --git a/opam/tezos-sc-rollup-015-PtLimaPt.opam b/opam/tezos-sc-rollup-015-PtLimaPt.opam deleted file mode 100644 index 1561973a3aa4ea9a7ac0cebb79be43aa934c94c4..0000000000000000000000000000000000000000 --- a/opam/tezos-sc-rollup-015-PtLimaPt.opam +++ /dev/null @@ -1,23 +0,0 @@ -# This file was automatically generated, do not edit. -# Edit file manifest/main.ml instead. -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" { >= "3.0" } - "ppx_expect" - "tezos-base" - "tezos-protocol-015-PtLimaPt" - "tezos-protocol-plugin-015-PtLimaPt" - "tezos-rpc" -] -build: [ - ["rm" "-r" "vendors"] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol specific library for `tezos-sc-rollup`" diff --git a/script-inputs/binaries-for-release b/script-inputs/binaries-for-release index 29176486a1a6e6d46aa71318851676192d0d0b0a..a2345ad139d85f9788d762177e4fef0dcc24200e 100644 --- a/script-inputs/binaries-for-release +++ b/script-inputs/binaries-for-release @@ -11,13 +11,9 @@ octez-accuser-alpha octez-baker-alpha octez-tx-rollup-node-PtLimaPt octez-tx-rollup-client-PtLimaPt -octez-sc-rollup-node-PtLimaPt -octez-sc-rollup-client-PtLimaPt octez-accuser-PtLimaPt octez-baker-PtLimaPt octez-tx-rollup-node-PtKathma octez-tx-rollup-client-PtKathma -octez-sc-rollup-node-PtKathma -octez-sc-rollup-client-PtKathma octez-accuser-PtKathma octez-baker-PtKathma diff --git a/script-inputs/static-packages b/script-inputs/static-packages index 82fcc6b711ac401e34ced76754d50d0a7bb82a5b..95e162041a12c64a95aafee50d593dea7da59503 100644 --- a/script-inputs/static-packages +++ b/script-inputs/static-packages @@ -10,11 +10,7 @@ octez-dal-node octez-node octez-protocol-compiler octez-proxy-server -octez-sc-rollup-client-PtKathma -octez-sc-rollup-client-PtLimaPt octez-sc-rollup-client-alpha -octez-sc-rollup-node-PtKathma -octez-sc-rollup-node-PtLimaPt octez-sc-rollup-node-alpha octez-signer octez-snoop diff --git a/src/bin_dal_node/dune b/src/bin_dal_node/dune index 1b671a359d439774794865c89fd4441e33a06a71..a27b9cbb52d7b8f97ecf43c8116b36d91a07c2b0 100644 --- a/src/bin_dal_node/dune +++ b/src/bin_dal_node/dune @@ -26,7 +26,6 @@ irmin-pack irmin-pack.unix irmin - tezos-dal-015-PtLimaPt (select void_for_linking-tezos-dal-alpha from (tezos-dal-alpha -> void_for_linking-tezos-dal-alpha.empty) (-> void_for_linking-tezos-dal-alpha.empty))) diff --git a/src/proto_013_PtJakart/lib_sc_rollup/dune b/src/proto_013_PtJakart/lib_sc_rollup/dune deleted file mode 100644 index 4cd4155522991b2ef09ffc42f95ca2c1eda5bd3e..0000000000000000000000000000000000000000 --- a/src/proto_013_PtJakart/lib_sc_rollup/dune +++ /dev/null @@ -1,23 +0,0 @@ -; This file was automatically generated, do not edit. -; Edit file manifest/main.ml instead. - -(library - (name tezos_sc_rollup_013_PtJakart) - (public_name tezos-sc-rollup-013-PtJakart) - (instrumentation (backend bisect_ppx)) - (libraries - tezos-base - tezos-protocol-013-PtJakart - tezos-protocol-plugin-013-PtJakart - tezos-protocol-013-PtJakart.parameters - tezos-rpc) - (inline_tests (flags -verbose) (modes native)) - (preprocess (pps ppx_expect)) - (library_flags (:standard -linkall)) - (flags - (:standard) - -open Tezos_base.TzPervasives - -open Tezos_protocol_013_PtJakart - -open Tezos_protocol_plugin_013_PtJakart - -open Tezos_protocol_013_PtJakart_parameters - -open Tezos_rpc)) diff --git a/src/proto_013_PtJakart/lib_sc_rollup/sc_rollup_services.ml b/src/proto_013_PtJakart/lib_sc_rollup/sc_rollup_services.ml deleted file mode 100644 index 0a64d5f4e905e5b29bed02321719fd45792ea5ce..0000000000000000000000000000000000000000 --- a/src/proto_013_PtJakart/lib_sc_rollup/sc_rollup_services.ml +++ /dev/null @@ -1,56 +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_rpc -open Protocol -open Alpha_context - -let sc_rollup_address () = - RPC_service.get_service - ~description:"Smart-contract rollup address" - ~query:RPC_query.empty - ~output:Sc_rollup.Address.encoding - RPC_path.(open_root / "sc_rollup_address") - -let current_tezos_head () = - RPC_service.get_service - ~description:"Tezos head known to the smart-contract rollup node" - ~query:RPC_query.empty - ~output:(Data_encoding.option Block_hash.encoding) - RPC_path.(open_root / "tezos_head") - -let current_tezos_level () = - RPC_service.get_service - ~description:"Tezos level known to the smart-contract rollup node" - ~query:RPC_query.empty - ~output:(Data_encoding.option Data_encoding.int32) - RPC_path.(open_root / "tezos_level") - -let current_inbox () = - RPC_service.get_service - ~description:"Current inbox" - ~query:RPC_query.empty - ~output:Sc_rollup.Inbox.encoding - RPC_path.(open_root / "inbox") diff --git a/src/proto_014_PtKathma/bin_sc_rollup_client/RPC.ml b/src/proto_014_PtKathma/bin_sc_rollup_client/RPC.ml deleted file mode 100644 index 5fca1cec64025d89bdcd311f5ab1d43700f041ea..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_client/RPC.ml +++ /dev/null @@ -1,31 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Configuration - -let call (cctxt : #sc_client_context) = cctxt#call_service - -let get_sc_rollup_addresses_command cctxt = - call cctxt (Sc_rollup_services.Global.sc_rollup_address ()) () () () diff --git a/src/proto_014_PtKathma/bin_sc_rollup_client/commands.ml b/src/proto_014_PtKathma/bin_sc_rollup_client/commands.ml deleted file mode 100644 index 4750ef242393223c0b9038d1107c9de02d1b1dcb..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_client/commands.ml +++ /dev/null @@ -1,151 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 Protocol.Alpha_context - -let get_sc_rollup_addresses_command () = - command - ~desc: - "Retrieve the smart-contract rollup address the node is interacting with." - no_options - (fixed ["get"; "sc"; "rollup"; "address"]) - (fun () (cctxt : #Configuration.sc_client_context) -> - RPC.get_sc_rollup_addresses_command cctxt >>=? fun addr -> - cctxt#message "@[%a@]" Sc_rollup.Address.pp addr >>= fun () -> return_unit) - -(** [display_answer cctxt answer] prints an RPC answer. *) -let display_answer (cctxt : #Configuration.sc_client_context) : - RPC_context.generic_call_result -> unit Lwt.t = function - | `Json (`Ok json) -> cctxt#answer "%a" Json_repr.(pp (module Ezjsonm)) json - | `Binary (`Ok binary) -> cctxt#answer "%a" Hex.pp (Hex.of_string binary) - | `Json (`Error (Some error)) -> - cctxt#error - "@[Command failed: @[%a@]@]@." - (Format.pp_print_list Error_monad.pp) - (Data_encoding.Json.destruct - (Data_encoding.list Error_monad.error_encoding) - error) - | `Binary (`Error (Some error)) -> ( - match Data_encoding.Binary.of_string Error_monad.trace_encoding error with - | Ok trace -> - cctxt#error - "@[Command failed: @[%a@]@]@." - Error_monad.pp_print_trace - trace - | Error msg -> - cctxt#error - "@[Error whilst decoding the server response: @[%a@]@]@." - Data_encoding.Binary.pp_read_error - msg) - | `Json (`Not_found _) | `Binary (`Not_found _) | `Other (_, `Not_found _) -> - cctxt#error "No service found at this URL\n%!" - | `Json (`Gone _) | `Binary (`Gone _) | `Other (_, `Gone _) -> - cctxt#error - "Requested data concerns a pruned block and target resource is no \ - longer available\n\ - %!" - | `Json (`Unauthorized _) - | `Binary (`Unauthorized _) - | `Other (_, `Unauthorized _) -> - cctxt#error "@[[HTTP 403] Access denied to: %a@]@." Uri.pp cctxt#base - | _ -> cctxt#error "Unexpected server answer\n%!" - -(** [call_get cctxt raw_url] executes a GET RPC call against the [raw_url]. *) -let call_get (cctxt : #Configuration.sc_client_context) raw_url = - let open Lwt_result_syntax in - let meth = `GET in - let uri = Uri.of_string raw_url in - let* answer = cctxt#generic_media_type_call meth uri in - let*! () = display_answer cctxt answer in - return_unit - -let rpc_get_command = - command - ~desc:"Call an RPC with the GET method." - no_options - (prefixes ["rpc"; "get"] @@ string ~name:"url" ~desc:"the RPC URL" @@ stop) - (fun () url cctxt -> call_get cctxt url) - -module Keys = struct - open Tezos_client_base.Client_keys - - let generate_keys () = - command - ~desc:"Generate a pair of keys." - (args1 (Secret_key.force_switch ())) - (prefixes ["gen"; "unencrypted"; "keys"] - @@ Aggregate_alias.Secret_key.fresh_alias_param @@ stop) - (fun force name (cctxt : #Configuration.sc_client_context) -> - Client_keys_commands.Bls_commands.generate_keys - ~force - ~encrypted:false - name - cctxt) - - let list_keys () = - command - ~desc:"List keys." - no_options - (prefixes ["list"; "keys"] @@ stop) - (fun () (cctxt : #Configuration.sc_client_context) -> - Client_keys_commands.Bls_commands.list_keys cctxt) - - let show_address () = - command - ~desc:"Show the keys associated with an account." - no_options - (prefixes ["show"; "address"] - @@ Aggregate_alias.Public_key_hash.alias_param @@ stop) - (fun () (name, _pkh) (cctxt : #Configuration.sc_client_context) -> - Client_keys_commands.Bls_commands.show_address - ~show_private:true - name - cctxt) - - let import_secret_key () = - command - ~desc:"Add a secret key to the wallet." - (args1 (Aggregate_alias.Secret_key.force_switch ())) - (prefixes ["import"; "secret"; "key"] - @@ Aggregate_alias.Secret_key.fresh_alias_param @@ aggregate_sk_uri_param - @@ stop) - (fun force name sk_uri (cctxt : #Configuration.sc_client_context) -> - Client_keys_commands.Bls_commands.import_secret_key - ~force - name - sk_uri - cctxt) -end - -let all () = - [ - get_sc_rollup_addresses_command (); - rpc_get_command; - Keys.generate_keys (); - Keys.list_keys (); - Keys.show_address (); - Keys.import_secret_key (); - ] diff --git a/src/proto_014_PtKathma/bin_sc_rollup_client/commands.mli b/src/proto_014_PtKathma/bin_sc_rollup_client/commands.mli deleted file mode 100644 index 32de9f752b330b75d04bd8dbe7fe69a72d21c3a6..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_client/commands.mli +++ /dev/null @@ -1,29 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 ()] is the list of commands recognized by the smart-contract - rollup client. These commands may depend on the client - configuration. *) -val all : unit -> Configuration.sc_client_context Clic.command list diff --git a/src/proto_014_PtKathma/bin_sc_rollup_client/configuration.ml b/src/proto_014_PtKathma/bin_sc_rollup_client/configuration.ml deleted file mode 100644 index 0de3f0b092ae18b710df38248925cf63af15b33a..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_client/configuration.ml +++ /dev/null @@ -1,113 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 Lwt_result_syntax -module Base = Tezos_client_base - -type t = {base_dir : string; endpoint : Uri.t} - -let default_base_dir = - Filename.concat (Sys.getenv "HOME") ".tezos-sc-rollup-client" - -let default_endpoint = "http://localhost:8932" - -let default = - {base_dir = default_base_dir; endpoint = Uri.of_string default_endpoint} - -let valid_endpoint _configuration s = - let endpoint = Uri.of_string s in - match (Uri.scheme endpoint, Uri.query endpoint, Uri.fragment endpoint) with - | Some ("http" | "https"), [], None -> return endpoint - | _ -> failwith "Endpoint should be of the form http[s]://address:port" - -let endpoint_arg () = - arg - ~long:"endpoint" - ~short:'E' - ~placeholder:"uri" - ~doc: - (Printf.sprintf - "endpoint of the sc rollup node; e.g. '%s'" - default_endpoint) - @@ parameter valid_endpoint - -let valid_base_dir _configuration base_dir = - if not (Sys.file_exists base_dir && Sys.is_directory base_dir) then - failwith "%s does not seem to be an existing directory" base_dir - else return base_dir - -let base_dir_arg () = - arg - ~long:"base-dir" - ~short:'d' - ~placeholder:"path" - ~doc: - (Format.asprintf - "@[@[<2>Tezos smart-contract rollup client data directory@,\ - The directory where the Tezos smart-contract rollup client stores \ - its data.@,\ - If absent, its value defaults to %s@]@]@." - default_base_dir) - (parameter valid_base_dir) - -let global_options () = Clic.args2 (base_dir_arg ()) (endpoint_arg ()) - -let make (base_dir, endpoint) = - { - base_dir = Option.value base_dir ~default:default_base_dir; - endpoint = Option.value endpoint ~default:(Uri.of_string default_endpoint); - } - -let parse argv = - let* opts, argv = - Clic.parse_global_options (global_options ()) default argv - in - return (make opts, argv) - -class type sc_client_context = - object - inherit Base.Client_context.io_wallet - - inherit RPC_context.generic - end - -class unix_sc_client_context ~base_dir ~password_filename ~rpc_config : - sc_client_context = - object - inherit Client_context_unix.unix_io_wallet ~base_dir ~password_filename - - inherit - Tezos_rpc_http_client_unix.RPC_client_unix.http_ctxt - rpc_config - (Tezos_rpc_http.Media_type.Command_line.of_command_line - rpc_config.media_type) - end - -let make_unix_client_context {base_dir; endpoint} = - let rpc_config = - {Tezos_rpc_http_client_unix.RPC_client_unix.default_config with endpoint} - in - new unix_sc_client_context ~base_dir ~rpc_config ~password_filename:None diff --git a/src/proto_014_PtKathma/bin_sc_rollup_client/configuration.mli b/src/proto_014_PtKathma/bin_sc_rollup_client/configuration.mli deleted file mode 100644 index 9aebfc3ba4b741d568d529020d5e650b630004d5..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_client/configuration.mli +++ /dev/null @@ -1,64 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 configuration. *) -type t = private { - base_dir : string; - (** [base_dir] is a directory where client user data is stored. *) - endpoint : Uri.t; - (** [endpoint] is used to communicate with the smart-contract rollup - node. *) -} - -(** [parse argv] parses command-line arguments to return - [(configuration, argv')] where [configuration] is deduced from the - command-line arguments and [argv'] is the rest of the command-line - arguments that have no meaning relatively to [Configuration]. *) -val parse : string list -> (t * string list) tzresult Lwt.t - -(** [global_options ()] returns the list of options that have an - influence on the configuration. *) -val global_options : unit -> (string option * Uri.t option, 'a) Clic.options - -(** Instance of [Tezos_client_base.Client_context] that only handles IOs and - RPCs. Can be used for keys and RPCs related commands. *) -class type sc_client_context = - object - inherit Tezos_client_base.Client_context.io_wallet - - inherit RPC_context.generic - end - -(** Instance of [sc_client_context] for linux systems. Relies on - [Tezos_rpc_http_client_unix]. *) -class unix_sc_client_context : - base_dir:string - -> password_filename:string option - -> rpc_config:Tezos_rpc_http_client_unix.RPC_client_unix.config - -> sc_client_context - -(** [make_unix_client_context config] generates a unix_sc_client_context from - the client configuration. *) -val make_unix_client_context : t -> unix_sc_client_context diff --git a/src/proto_014_PtKathma/bin_sc_rollup_client/dune b/src/proto_014_PtKathma/bin_sc_rollup_client/dune deleted file mode 100644 index 43431f89f6cd216600182c324b89605e3e92cbe3..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_client/dune +++ /dev/null @@ -1,36 +0,0 @@ -; This file was automatically generated, do not edit. -; Edit file manifest/main.ml instead. - -(executable - (name main_sc_rollup_client_014_PtKathma) - (public_name octez-sc-rollup-client-PtKathma) - (package octez-sc-rollup-client-PtKathma) - (instrumentation (backend bisect_ppx)) - (libraries - tezos-base - tezos-clic - tezos-client-base - tezos-client-014-PtKathma - tezos-client-commands - tezos-stdlib-unix - tezos-client-base-unix - tezos-rpc-http - tezos-rpc-http-client-unix - tezos-protocol-014-PtKathma - tezos-sc-rollup-014-PtKathma - uri) - (link_flags - (:standard) - (:include %{workspace_root}/static-link-flags.sexp)) - (flags - (:standard) - -open Tezos_base.TzPervasives - -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals - -open Tezos_clic - -open Tezos_client_014_PtKathma - -open Tezos_client_commands - -open Tezos_stdlib_unix - -open Tezos_client_base_unix - -open Tezos_rpc_http_client_unix - -open Tezos_protocol_014_PtKathma - -open Tezos_sc_rollup_014_PtKathma)) diff --git a/src/proto_014_PtKathma/bin_sc_rollup_client/main_sc_rollup_client_014_PtKathma.ml b/src/proto_014_PtKathma/bin_sc_rollup_client/main_sc_rollup_client_014_PtKathma.ml deleted file mode 100644 index 5d7ada1f54cee7a1893645f2fab4f1683fea6d5d..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_client/main_sc_rollup_client_014_PtKathma.ml +++ /dev/null @@ -1,59 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 executable_name = Filename.basename Sys.executable_name - -let argv () = Array.to_list Sys.argv |> List.tl |> Stdlib.Option.get - -let main () = - Configuration.parse (argv ()) >>=? fun (configuration, argv) -> - let cctxt = Configuration.make_unix_client_context configuration in - Tezos_client_base.Client_keys.register_aggregate_signer - (module Tezos_signer_backends.Unencrypted.Aggregate) ; - Clic.dispatch (Commands.all ()) cctxt argv - -let handle_error = function - | Ok () -> Stdlib.exit 0 - | Error [Clic.Version] -> - let version = Tezos_version.Bin_version.version_string in - Format.printf "%s\n" version ; - Stdlib.exit 0 - | Error [Clic.Help command] -> - Clic.usage - Format.std_formatter - ~executable_name - ~global_options:(Configuration.global_options ()) - (match command with None -> [] | Some c -> [c]) ; - Stdlib.exit 0 - | Error errs -> - Clic.pp_cli_errors - Format.err_formatter - ~executable_name - ~global_options:(Configuration.global_options ()) - ~default:Error_monad.pp - errs ; - Stdlib.exit 1 - -let () = Lwt_main.run (Lwt.catch main fail_with_exn) |> handle_error diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/RPC_server.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/RPC_server.ml deleted file mode 100644 index ce6dfb9c4402e410ce4b5a83aac2299dedcce3a7..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/RPC_server.ml +++ /dev/null @@ -1,235 +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_rpc -open Tezos_rpc_http -open Tezos_rpc_http_server - -let get_head_exn store = - let open Lwt_result_syntax in - let*! head = Layer1.current_head_hash store in - match head with None -> failwith "No head" | Some head -> return head - -let get_state_exn store = - let open Lwt_result_syntax in - let* head = get_head_exn store in - let*! state = Store.PVMState.find store head in - match state with None -> failwith "No state" | Some state -> return state - -let get_state_info_exn store = - let open Lwt_result_syntax in - let* head = get_head_exn store in - let*! state = Store.StateInfo.get store head in - return state - -let get_dal_slot_subscriptions_exn store = - let open Lwt_result_syntax in - let* head = get_head_exn store in - let*! slot_subscriptions = Store.Dal_slot_subscriptions.find store head in - match slot_subscriptions with - | None -> failwith "No slot subscriptions" - | Some slot_subscriptions -> return slot_subscriptions - -let commitment_with_hash commitment = - (Protocol.Alpha_context.Sc_rollup.Commitment.hash commitment, commitment) - -module Common = struct - let register_current_num_messages store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_num_messages ()) - (fun () () -> - let open Lwt_result_syntax in - let* state_info = get_state_info_exn store in - return state_info.num_messages) - - let register_sc_rollup_address configuration dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.sc_rollup_address ()) - (fun () () -> return @@ configuration.Configuration.sc_rollup_address) - - let register_current_tezos_head store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_tezos_head ()) - (fun () () -> Layer1.current_head_hash store >>= return) - - let register_current_tezos_level store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_tezos_level ()) - (fun () () -> Layer1.current_level store >>= return) - - let register_current_inbox node_ctxt store dir = - let open Lwt_result_syntax in - RPC_directory.opt_register0 - dir - (Sc_rollup_services.Global.current_inbox ()) - (fun () () -> - Layer1.current_head_hash store >>= function - | Some head_hash -> - let*! inbox = Inbox.inbox_of_hash node_ctxt store head_hash in - return_some inbox - | None -> return None) - - let register_current_ticks store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_ticks ()) - (fun () () -> - let open Lwt_result_syntax in - let* state = get_state_info_exn store in - return state.num_ticks) - - let start configuration dir = - let Configuration.{rpc_addr; rpc_port; _} = configuration in - let rpc_addr = P2p_addr.of_string_exn rpc_addr in - let host = Ipaddr.V6.to_string rpc_addr in - let node = `TCP (`Port rpc_port) in - let acl = RPC_server.Acl.default rpc_addr in - Lwt.catch - (fun () -> - RPC_server.launch - ~media_types:Media_type.all_media_types - ~host - ~acl - node - dir - >>= return) - fail_with_exn - - let shutdown = RPC_server.shutdown -end - -module type S = sig - module PVM : Pvm.S - - val shutdown : RPC_server.server -> unit Lwt.t - - val register : - Node_context.t -> PVM.context -> Configuration.t -> unit RPC_directory.t - - val start : - Node_context.t -> - PVM.context -> - Configuration.t -> - RPC_server.server tzresult Lwt.t -end - -module Make (PVM : Pvm.S) : S with module PVM = PVM = struct - include Common - module PVM = PVM - - let register_current_total_ticks store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_total_ticks ()) - (fun () () -> - let open Lwt_result_syntax in - let* state = get_state_exn store in - let*! tick = PVM.get_tick state in - return tick) - - let register_current_state_hash store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_state_hash ()) - (fun () () -> - let open Lwt_result_syntax in - let* state = get_state_exn store in - let*! hash = PVM.state_hash state in - return hash) - - let register_last_stored_commitment store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.last_stored_commitment ()) - (fun () () -> - let open Lwt_result_syntax in - let*! commitment_with_hash = - Commitment.last_commitment_with_hash - (module Store.Last_stored_commitment_level) - store - in - return - (commitment_with_hash - |> Option.map (fun (commitment, hash) -> (commitment, hash, None)))) - - let register_last_published_commitment store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Local.last_published_commitment ()) - (fun () () -> - let open Lwt_result_syntax in - let*! result = - let open Lwt_option_syntax in - let* commitment, hash = - Commitment.last_commitment_with_hash - (module Store.Last_published_commitment_level) - store - in - (* If the commitment has been published then the corresponding - level in Store.Commitments.published_at_level is available. *) - let*! published_at_level = - Store.Commitments_published_at_level.get store hash - in - return (commitment, hash, Some published_at_level) - in - return result) - - let register_current_status store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_status ()) - (fun () () -> - let open Lwt_result_syntax in - let* state = get_state_exn store in - let*! status = PVM.get_status state in - return (PVM.string_of_status status)) - - let register_dal_slot_subscriptions store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.dal_slot_subscriptions ()) - (fun () () -> get_dal_slot_subscriptions_exn store) - - let register node_ctxt store configuration = - RPC_directory.empty - |> register_sc_rollup_address configuration - |> register_current_tezos_head store - |> register_current_inbox node_ctxt store - |> register_current_ticks store - |> register_current_total_ticks store - |> register_current_num_messages store - |> register_current_state_hash store - |> register_current_status store - |> register_last_stored_commitment store - |> register_last_published_commitment store - |> register_dal_slot_subscriptions store - - let start node_ctxt store configuration = - Common.start configuration (register node_ctxt store configuration) -end diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/arith_pvm.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/arith_pvm.ml deleted file mode 100644 index 2410bf07521b1be40cf01929e967325032da9e7c..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/arith_pvm.ml +++ /dev/null @@ -1,93 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 manifests the proof format used by the Arith PVM as defined by - the Layer 1 implementation for it. - - It is imperative that this is aligned with the protocol's implementation. -*) -module Arith_proof_format = struct - open Store - - type proof = IStoreProof.Proof.tree IStoreProof.Proof.t - - let verify_proof proof step = - (* The rollup node is not supposed to verify proof. We keep - this part in case this changes in the future. *) - let open Lwt_syntax in - let* result = IStoreProof.verify_tree_proof proof step in - match result with - | Ok v -> return (Some v) - | Error _ -> - (* We skip the error analysis here since proof verification is not a - job for the rollup node. *) - return None - - let produce_proof context tree step = - let open Lwt_syntax in - match IStoreTree.kinded_key tree with - | Some k -> - let* p = IStoreProof.produce_tree_proof (IStore.repo context) k step in - return (Some p) - | None -> return None - - let kinded_hash_to_state_hash : - IStoreProof.Proof.kinded_hash -> Sc_rollup.State_hash.t = function - | `Value hash | `Node hash -> - Sc_rollup.State_hash.hash_bytes [Context_hash.to_bytes hash] - - let proof_before proof = - kinded_hash_to_state_hash proof.IStoreProof.Proof.before - - let proof_after proof = - kinded_hash_to_state_hash proof.IStoreProof.Proof.after - - let proof_encoding = - Tezos_context_merkle_proof_encoding.Merkle_proof_encoding.V1.Tree32 - .tree_proof_encoding -end - -module Impl : Pvm.S = struct - include Sc_rollup.ArithPVM.Make (struct - open Store - module Tree = IStoreTree - - type tree = IStoreTree.tree - - include Arith_proof_format - end) - - let string_of_status status = - match status with - | Halted -> "Halted" - | WaitingForInputMessage -> "WaitingForInputMessage" - | Parsing -> "Parsing" - | Evaluating -> "Evaluating" -end - -include Impl diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/commitment.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/commitment.ml deleted file mode 100644 index 71c6dafce30c2d202a14dd81764eb98d142f4368..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/commitment.ml +++ /dev/null @@ -1,443 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 rollup node stores and publishes commitments for the PVM - every 20 levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to 20 blocks earlier. In this case, it - computes and stores a new commitment in a level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) - -open Protocol -open Alpha_context - -module type Mutable_level_store = - Store.Mutable_value with type value = Raw_level.t - -(* We keep the number of messages and ticks to be included in the - next commitment in memory. Note that we do not risk to increase - these counters when the wrong branch is tracked by the rollup - node, as only finalized heads are processed to build commitments. -*) - -(* FIXME: #3203 - - Using these global variables is fragile considering chain - reorganizations and interruptions. We should use a more persistent - representations for this piece of information. *) -module Mutable_counter = struct - module Make () = struct - let x = ref Z.zero - - let add z = x := Z.add !x z - - let reset () = x := Z.zero - - let get () = !x - end -end - -module Number_of_messages = Mutable_counter.Make () - -module Number_of_ticks = Mutable_counter.Make () - -let sc_rollup_commitment_period = - (* FIXME: https://gitlab.com/tezos/tezos/-/issues/2977 - Use effective on-chain protocol parameter. *) - Int32.of_int - Default_parameters.constants_mainnet.sc_rollup.commitment_period_in_blocks - -let sc_rollup_challenge_window = - (* FIXME: https://gitlab.com/tezos/tezos/-/issues/2977 - Use effective on-chain protocol parameter. *) - Int32.of_int - Default_parameters.constants_mainnet.sc_rollup.challenge_window_in_blocks - -let last_commitment_level (module Last_commitment_level : Mutable_level_store) - store = - Last_commitment_level.find store - -let last_commitment_with_hash - (module Last_commitment_level : Mutable_level_store) store = - let open Lwt_option_syntax in - let* last_commitment_level = - last_commitment_level (module Last_commitment_level) store - in - let*! commitment_with_hash = - Store.Commitments.get store last_commitment_level - in - return commitment_with_hash - -let last_commitment (module Last_commitment_level : Mutable_level_store) store = - let open Lwt_option_syntax in - let+ commitment, _hash = - last_commitment_with_hash (module Last_commitment_level) store - in - commitment - -let next_commitment_level (module Last_commitment_level : Mutable_level_store) - ~origination_level store = - let open Lwt_syntax in - let+ last_commitment_level_opt = - last_commitment_level (module Last_commitment_level) store - in - let last_commitment_level = - Option.value last_commitment_level_opt ~default:origination_level - in - Raw_level.of_int32 - @@ Int32.add - (Raw_level.to_int32 last_commitment_level) - sc_rollup_commitment_period - -let last_commitment_hash (module Last_commitment_level : Mutable_level_store) - store = - let open Lwt_syntax in - let+ last_commitment = last_commitment (module Last_commitment_level) store in - match last_commitment with - | Some commitment -> Sc_rollup.Commitment.hash commitment - | None -> Sc_rollup.Commitment.Hash.zero - -let must_store_commitment ~origination_level current_level store = - let open Lwt_result_syntax in - let+ next_commitment_level = - next_commitment_level - (module Store.Last_stored_commitment_level) - ~origination_level - store - in - Raw_level.equal current_level next_commitment_level - -let update_last_stored_commitment store (commitment : Sc_rollup.Commitment.t) = - let open Lwt_syntax in - let commitment_hash = Sc_rollup.Commitment.hash commitment in - let inbox_level = commitment.inbox_level in - let* lcc_level = Store.Last_cemented_commitment_level.get store in - (* Do not change the order of these two operations. This guarantees that - whenever `Store.Last_stored_commitment_level.get` returns `Some hash`, - then the call to `Store.Commitments.get hash` will succeed. - *) - let* () = - Store.Commitments.add store inbox_level (commitment, commitment_hash) - in - let* () = Store.Last_stored_commitment_level.set store inbox_level in - let* () = Commitment_event.commitment_stored commitment in - if commitment.inbox_level <= lcc_level then - Commitment_event.commitment_will_not_be_published lcc_level commitment - else return () - -module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct - module PVM = PVM - - let build_commitment ~origination_level store block_hash = - let open Lwt_result_syntax in - let lsc = - (module Store.Last_stored_commitment_level : Mutable_level_store) - in - let*! predecessor = last_commitment_hash lsc store in - let* inbox_level = - Lwt.map Environment.wrap_tzresult - @@ next_commitment_level ~origination_level lsc store - in - let*! pvm_state = Store.PVMState.find store block_hash in - let* compressed_state = - match pvm_state with - | Some pvm_state -> - let*! hash = PVM.state_hash pvm_state in - return hash - | None -> - failwith - "PVM state for block hash not available %s" - (Block_hash.to_string block_hash) - in - let number_of_messages = Number_of_messages.get () in - let* number_of_messages = - match - Sc_rollup.Number_of_messages.of_int32 @@ Z.to_int32 number_of_messages - with - | Some number_of_messages -> return number_of_messages - | None -> - failwith - "Invalid number of messages %s" - (Z.to_string number_of_messages) - in - let number_of_ticks = Number_of_ticks.get () in - let+ number_of_ticks = - match - Sc_rollup.Number_of_ticks.of_int32 @@ Z.to_int32 number_of_ticks - with - | Some number_of_ticks -> return number_of_ticks - | None -> - failwith "Invalid number of ticks %s" (Z.to_string number_of_ticks) - in - (* Reset counters for messages as the commitment to be published - has been built. - *) - let () = Number_of_messages.reset () in - let () = Number_of_ticks.reset () in - Sc_rollup.Commitment. - { - predecessor; - inbox_level; - number_of_messages; - number_of_ticks; - compressed_state; - } - - let store_commitment_if_necessary ~origination_level store current_level - block_hash = - let open Lwt_result_syntax in - let* must_store_commitment = - Lwt.map Environment.wrap_tzresult - @@ must_store_commitment ~origination_level current_level store - in - if must_store_commitment then - let*! () = Commitment_event.compute_commitment block_hash current_level in - let* commitment = build_commitment ~origination_level store block_hash in - let*! () = update_last_stored_commitment store commitment in - return_unit - else return_unit - - let update_ticks_and_messages store block_hash = - let open Lwt_result_syntax in - let*! {num_messages; num_ticks} = Store.StateInfo.get store block_hash in - let () = Number_of_messages.add num_messages in - return @@ Number_of_ticks.add num_ticks - - let process_head (node_ctxt : Node_context.t) store - Layer1.(Head {level; hash}) = - let open Lwt_result_syntax in - let current_level = Raw_level.of_int32_exn level in - let origination_level = node_ctxt.initial_level in - let* () = update_ticks_and_messages store hash in - store_commitment_if_necessary ~origination_level store current_level hash - - let sync_last_cemented_commitment_hash_with_level - ({cctxt; rollup_address; _} : Node_context.t) store = - let open Lwt_result_syntax in - let* hash, inbox_level = - Plugin.RPC.Sc_rollup.last_cemented_commitment_hash_with_level - cctxt - (cctxt#chain, cctxt#block) - rollup_address - in - let*! () = Store.Last_cemented_commitment_level.set store inbox_level in - let*! () = Store.Last_cemented_commitment_hash.set store hash in - let*! () = - Commitment_event.last_cemented_commitment_updated hash inbox_level - in - return_unit - - let get_commitment_and_publish ~check_lcc_hash - ({cctxt; rollup_address; _} as node_ctxt : Node_context.t) - next_level_to_publish store = - let open Lwt_result_syntax in - let*! is_commitment_available = - Store.Commitments.mem store next_level_to_publish - in - if is_commitment_available then - let*! commitment, commitment_hash = - Store.Commitments.get store next_level_to_publish - in - let*! () = - if check_lcc_hash then - let open Lwt_syntax in - let* lcc_hash = Store.Last_cemented_commitment_hash.get store in - if Sc_rollup.Commitment.Hash.equal lcc_hash commitment.predecessor - then return () - else - let+ () = - Commitment_event.commitment_parent_is_not_lcc - commitment.inbox_level - commitment.predecessor - lcc_hash - in - exit 1 - else Lwt.return () - in - let* source, src_pk, src_sk = Node_context.get_operator_keys node_ctxt in - let* _, _, Manager_operation_result {operation_result; _} = - Client_proto_context.sc_rollup_publish - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~commitment - ~source - ~rollup:rollup_address - ~src_pk - ~src_sk - ~fee_parameter:Configuration.default_fee_parameter - () - in - let open Apply_results in - let*! () = - match operation_result with - | Applied (Sc_rollup_publish_result {published_at_level; _}) -> - let open Lwt_syntax in - let* () = - Store.Last_published_commitment_level.set - store - commitment.inbox_level - in - let* () = - Store.Commitments_published_at_level.add - store - commitment_hash - published_at_level - in - Commitment_event.publish_commitment_injected commitment - | Failed (Sc_rollup_publish_manager_kind, _errors) -> - Commitment_event.publish_commitment_failed commitment - | Backtracked (Sc_rollup_publish_result _, _errors) -> - Commitment_event.publish_commitment_backtracked commitment - | Skipped Sc_rollup_publish_manager_kind -> - Commitment_event.publish_commitment_skipped commitment - in - return_unit - else return_unit - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2869 - use the Injector to publish commitments. *) - let publish_commitment node_ctxt store = - let open Lwt_result_syntax in - let open Node_context in - let origination_level = node_ctxt.initial_level in - (* Check level of next publishable commitment and avoid publishing if it is - on or before the last cemented commitment. - *) - let* next_lcc_level = - Lwt.map Environment.wrap_tzresult - @@ next_commitment_level - (module Store.Last_cemented_commitment_level) - ~origination_level - store - in - let* next_publishable_level = - Lwt.map Environment.wrap_tzresult - @@ next_commitment_level - (module Store.Last_published_commitment_level) - ~origination_level - store - in - let check_lcc_hash, level_to_publish = - if Raw_level.(next_publishable_level < next_lcc_level) then - (true, next_lcc_level) - else (false, next_publishable_level) - in - get_commitment_and_publish node_ctxt level_to_publish store ~check_lcc_hash - - let earliest_cementing_level store commitment_hash = - let open Lwt_option_syntax in - let+ published_at_level = - Store.Commitments_published_at_level.find store commitment_hash - in - Int32.add (Raw_level.to_int32 published_at_level) sc_rollup_challenge_window - - let can_be_cemented earliest_cementing_level head_level = - earliest_cementing_level <= head_level - - let cement_commitment ({Node_context.cctxt; rollup_address; _} as node_ctxt) - ({Sc_rollup.Commitment.inbox_level; _} as commitment) commitment_hash - store = - let open Lwt_result_syntax in - let* source, src_pk, src_sk = Node_context.get_operator_keys node_ctxt in - let* _, _, Manager_operation_result {operation_result; _} = - Client_proto_context.sc_rollup_cement - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~commitment:commitment_hash - ~source - ~rollup:rollup_address - ~src_pk - ~src_sk - ~fee_parameter:Configuration.default_fee_parameter - () - in - let open Apply_results in - let*! () = - match operation_result with - | Applied (Sc_rollup_cement_result _) -> - let open Lwt_syntax in - let* () = - Store.Last_cemented_commitment_level.set store inbox_level - in - let* () = - Store.Last_cemented_commitment_hash.set store commitment_hash - in - Commitment_event.cement_commitment_injected commitment - | Failed (Sc_rollup_cement_manager_kind, _errors) -> - Commitment_event.cement_commitment_failed commitment - | Backtracked (Sc_rollup_cement_result _, _errors) -> - Commitment_event.cement_commitment_backtracked commitment - | Skipped Sc_rollup_cement_manager_kind -> - Commitment_event.cement_commitment_skipped commitment - in - return_unit - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3008 - Use the injector to cement commitments. *) - let cement_commitment_if_possible - ({Node_context.initial_level = origination_level; _} as node_ctxt) store - (Layer1.Head {level = head_level; _}) = - let open Lwt_result_syntax in - let* next_level_to_cement = - Lwt.map Environment.wrap_tzresult - @@ next_commitment_level - ~origination_level - (module Store.Last_cemented_commitment_level) - store - in - let*! commitment_with_hash = - Store.Commitments.find store next_level_to_cement - in - match commitment_with_hash with - (* If `commitment_with_hash` is defined, the commitment to be cemented has - been stored but not necessarily published by the rollup node. *) - | Some (commitment, commitment_hash) -> ( - let*! earliest_cementing_level = - earliest_cementing_level store commitment_hash - in - match earliest_cementing_level with - (* If `earliest_cementing_level` is well defined, then the rollup node - has previously published `commitment`, which means that the rollup - is indirectly staked on it. *) - | Some earliest_cementing_level -> - if can_be_cemented earliest_cementing_level head_level then - cement_commitment node_ctxt commitment commitment_hash store - else return () - | None -> return ()) - | None -> return () - - let start () = Commitment_event.starting () -end diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/commitment.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/commitment.mli deleted file mode 100644 index b05c172527d9eecba105f3f3f97f42bd5ff2d266..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/commitment.mli +++ /dev/null @@ -1,62 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 rollup node stores and publishes commitments for the PVM - every 20 levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to 20 blocks earlier. In this case, it - computes and stores a new commitment in a level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) - -open Protocol.Alpha_context - -module type Mutable_level_store = - Store.Mutable_value with type value = Raw_level.t - -(** [last_commitment_with_hash (module Last_level_module: Mutable_level_store) store] - returns the last commitment and relative hash - stored according to the value of level indicated by - [module Last_level_module]. If no commitment has been stored for the - level indicated by [module Last_level_module], then None is returned. - Two possible implementations for [module Last_level_module] are - [Store.Last_published_commitment_level] and - [Store.Last_stored_commitment_level]. - *) - -val last_commitment_with_hash : - (module Mutable_level_store) -> - Store.t -> - (Sc_rollup.Commitment.t * Sc_rollup.Commitment.Hash.t) option Lwt.t - -module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/commitment_event.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/commitment_event.ml deleted file mode 100644 index 08eec01be2b733d9f30749854787acfaf704f192..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/commitment_event.ml +++ /dev/null @@ -1,259 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; "commitment"] - - let event_name ?op_result op_type = - let op_type_string = - match op_type with - | `Cement -> "cement" - | `Publish -> "publish" - | `Store -> "stored" - in - let op_result_string_opt = - op_result - |> Option.map (function - | `Injected -> "injected" - | `Backtracked -> "backtracked" - | `Skipped -> "skipped" - | `Failed -> "failed") - in - match op_result_string_opt with - | None -> "sc_rollup_node_commitment_" ^ op_type_string - | Some op_result_string -> - "sc_rollup_" ^ op_type_string ^ "_commitment_" ^ op_result_string - - let event_msg_prefix ?op_result op_type = - let op_type_string = - match op_type with - | `Cement -> "Cementing" - | `Publish -> "Publishing" - | `Store -> "was stored" - in - let op_result_string_opt = - op_result - |> Option.map (function - | `Injected -> "was injected" - | `Backtracked -> "was backtracked" - | `Skipped -> "was skipped" - | `Failed -> "has failed") - in - match op_result_string_opt with - | None -> "Commitment " ^ op_type_string - | Some op_result_string -> - op_type_string ^ " Commitment " ^ op_result_string - - let commitment_event ?op_result op_type = - let name = event_name ?op_result op_type in - let msg = - event_msg_prefix ?op_result op_type - ^ " - predecessor: {predecessor}, inbox_level: {inbox_level}, \ - compressed_state: {compressed_state}, number_of_messages: \ - {number_of_messages}, number_of_ticks: {number_of_ticks}" - in - declare_5 - ~section - ~name - ~msg - ~level:Notice - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_messages", Sc_rollup.Number_of_messages.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) - - let starting = - declare_0 - ~section - ~name:"sc_rollup_commitment_publisher_starting" - ~msg:"Starting commitment publisher for the smart contract rollup node" - ~level:Notice - () - - let stopping = - declare_0 - ~section - ~name:"sc_rollup_node_commitment_publisher_stopping" - ~msg:"Stopping commitment publisher for the smart contract rollup node" - ~level:Notice - () - - let commitment_will_not_be_published = - declare_6 - ~section - ~name:"sc_rollup_node_commitment_will_not_be_published" - ~msg: - "Commitment will not be published: its inbox level is less or equal \ - than the last cemented commitment level {lcc_level} - predecessor: \ - {predecessor}, inbox_level: {inbox_level}, compressed_state: \ - {compressed_state}, number_of_messages: {number_of_messages}, \ - number_of_ticks: {number_of_ticks}" - ~level:Notice - ("lcc_level", Raw_level.encoding) - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_messages", Sc_rollup.Number_of_messages.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) - - let last_cemented_commitment_updated = - declare_2 - ~section - ~name:"sc_rollup_node_lcc_updated" - ~msg: - "Last cemented commitment was updated to hash {hash} at inbox level \ - {level}" - ~level:Notice - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) - - let compute_commitment = - declare_2 - ~section - ~name:"sc_rollup_node_commitment_process_head" - ~msg: - "Computing and storing new commitment for head {head} at level {level}" - ~level:Notice - ("head", Block_hash.encoding) - ("level", Raw_level.encoding) - - let commitment_parent_is_not_lcc = - declare_3 - ~section - ~name:"sc_rollup_commitment_parent_is_not_lcc" - ~msg: - "Trying to publish a commitment at inbox level {level} whose parent is \ - the last cemented commitment, but the commitment's predecessor hash \ - {predecessor_hash} differs from the last cemented commitment hash \ - {lcc_hash}. This is a critical error, and the rollup node will be \ - terminated." - ~level:Fatal - ("level", Raw_level.encoding) - ("predecessor_hash", Sc_rollup.Commitment.Hash.encoding) - ("lcc_hash", Sc_rollup.Commitment.Hash.encoding) - - let commitment_stored = commitment_event `Store - - let publish_commitment_injected = - commitment_event `Publish ~op_result:`Injected - - let publish_commitment_backtracked = - commitment_event `Publish ~op_result:`Backtracked - - let publish_commitment_skipped = commitment_event `Publish ~op_result:`Skipped - - let publish_commitment_failed = commitment_event `Publish ~op_result:`Failed - - let cement_commitment_injected = commitment_event `Cement ~op_result:`Injected - - let cement_commitment_backtracked = - commitment_event `Cement ~op_result:`Backtracked - - let cement_commitment_skipped = commitment_event `Cement ~op_result:`Skipped - - let cement_commitment_failed = commitment_event `Cement ~op_result:`Failed -end - -let starting = Simple.(emit starting) - -let stopping = Simple.(emit stopping) - -open Sc_rollup.Commitment - -let emit_commitment_event f - { - predecessor; - inbox_level; - compressed_state; - number_of_messages; - number_of_ticks; - } = - Simple.( - emit - f - ( predecessor, - inbox_level, - compressed_state, - number_of_messages, - number_of_ticks )) - -let commitment_will_not_be_published lcc_level - { - predecessor; - inbox_level; - compressed_state; - number_of_messages; - number_of_ticks; - } = - Simple.( - emit - commitment_will_not_be_published - ( lcc_level, - predecessor, - inbox_level, - compressed_state, - number_of_messages, - number_of_ticks )) - -let commitment_stored = emit_commitment_event Simple.commitment_stored - -let publish_commitment_injected = - emit_commitment_event Simple.publish_commitment_injected - -let publish_commitment_skipped = - emit_commitment_event Simple.publish_commitment_skipped - -let publish_commitment_backtracked = - emit_commitment_event Simple.publish_commitment_backtracked - -let publish_commitment_failed = - emit_commitment_event Simple.publish_commitment_failed - -let cement_commitment_injected = - emit_commitment_event Simple.cement_commitment_injected - -let cement_commitment_skipped = - emit_commitment_event Simple.cement_commitment_skipped - -let cement_commitment_backtracked = - emit_commitment_event Simple.cement_commitment_backtracked - -let cement_commitment_failed = - emit_commitment_event Simple.cement_commitment_failed - -let last_cemented_commitment_updated head level = - Simple.(emit last_cemented_commitment_updated (head, level)) - -let compute_commitment head level = - Simple.(emit compute_commitment (head, level)) - -let commitment_parent_is_not_lcc level predecessor_hash lcc_hash = - Simple.(emit commitment_parent_is_not_lcc (level, predecessor_hash, lcc_hash)) diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/commitment_event.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/commitment_event.mli deleted file mode 100644 index 0b94e86ab11369c5fe5227de0184dcbb78fb345c..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/commitment_event.mli +++ /dev/null @@ -1,89 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 functions that emit the events used for the rollup node - when it is storing and publishing commitments (see {!Commitment}). *) - -open Protocol.Alpha_context - -val starting : unit -> unit Lwt.t - -val stopping : unit -> unit Lwt.t - -(** The commitment functions below emit events depending on whether they are - being published or cemented, along with their status: - * backtracked; - * skipped; - * injected; - or if it has failed. *) - -val publish_commitment_failed : Sc_rollup.Commitment.t -> unit Lwt.t - -val publish_commitment_backtracked : Sc_rollup.Commitment.t -> unit Lwt.t - -val publish_commitment_skipped : Sc_rollup.Commitment.t -> unit Lwt.t - -val publish_commitment_injected : Sc_rollup.Commitment.t -> unit Lwt.t - -val cement_commitment_failed : Sc_rollup.Commitment.t -> unit Lwt.t - -val cement_commitment_backtracked : Sc_rollup.Commitment.t -> unit Lwt.t - -val cement_commitment_skipped : Sc_rollup.Commitment.t -> unit Lwt.t - -val cement_commitment_injected : Sc_rollup.Commitment.t -> unit Lwt.t - -(** [commitment_stored commitment] emits the event that the [commitment] was - stored. *) -val commitment_stored : Sc_rollup.Commitment.t -> unit Lwt.t - -(** [commitment_will_not_be_published level commitment] emits the event that - [commitment] will not be published: its inbox level is less or equal than - the last cemented commitment [level]. *) -val commitment_will_not_be_published : - Raw_level.t -> Sc_rollup.Commitment.t -> unit Lwt.t - -(** [last_cemented_commitment_updated hash level] emits the event that the last - cemented commitment was updated to the given [hash] at the given inbox - [level]. *) -val last_cemented_commitment_updated : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t - -(** [commitment_parent_is_not_lcc predecessor_hash last_cemented_commitment_hash] - emits the event that a commitment at the given inbox [level] is being - published, whose parent is the last cemented commitment, but the - commitment's [predecessor_hash] differs from the - [last_cemented_commitment_hash]. - This is a critical error, the rollup node will be terminated. *) -val commitment_parent_is_not_lcc : - Raw_level.t -> - Sc_rollup.Commitment.Hash.t -> - Sc_rollup.Commitment.Hash.t -> - unit Lwt.t - -(** [compute_commitment hash level] emits the event that a new commitment is - being computed and stored for the block of the given [hash] and at the given - [level]. *) -val compute_commitment : Block_hash.t -> Raw_level.t -> unit Lwt.t diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/commitment_sig.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/commitment_sig.ml deleted file mode 100644 index ea17b2100f4e1a90268523f748865edafaddbb0b..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/commitment_sig.ml +++ /dev/null @@ -1,95 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 rollup node stores and publishes commitments for the PVM - every `Commitment.sc_rollup_commitment_period` levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to `Commitment.sc_rollup_commitment_period` blocks - earlier. In this case, it computes and stores a new commitment in a - level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) -module type S = sig - module PVM : Pvm.S - - (** [process_head node_ctxt store head] checks whether a new commitment needs - to be computed and stored, by looking at the level of [head] and checking - whether it is a multiple of `Commitment.sc_rollup_commitment_period` - levels away from [node_ctxt.initial_level]. It uses the functionalities - of [PVM] to compute the hash of to be included in the commitment. - *) - val process_head : - Node_context.t -> Store.t -> Layer1.head -> unit tzresult Lwt.t - - (** [sync_last_cemented_commitment_hash_with_level node_ctxt store] - fetches and stores information about the last cemeneted commitment - in the layer1 chain. - *) - val sync_last_cemented_commitment_hash_with_level : - Node_context.t -> Store.t -> unit tzresult Lwt.t - - (** [publish_commitment node_ctxt store] publishes the earliest commitment - stored in [store] that has not been published yet, unless its inbox level - is below or equal to the inbox level of the last cemented commitment in - the layer1 chain. In this case, the rollup node checks whether it has - computed a commitment whose inbox level is - [sc_rollup_commitment_period] levels after the inbox level of the last - cemented commitment: - {ul - {li if the commitment is found and its predecessor hash coincides with - the hash of the LCC, the rollup node will try to publish that commitment - instead; } - {li if the commitment is found but its predecessor hash differs from the - hash of the LCC, the rollup node will stop its execution;} - {li if no commitment is found, no action is taken by the rollup node; - in particular, no commitment is published.} - } - *) - val publish_commitment : Node_context.t -> Store.t -> unit tzresult Lwt.t - - (** [cement_commitment_if_possible node_ctxt store head] checks whether the - next commitment to be cemented (i.e. whose inbox level is - [sc_rollup_commitment_period] levels after - [Store.Last_cemented_commitment_level store]) can be cemented. In - particular, the request to cement the commitment happens only if the - commitment is stored in [Store.Commitments store], and if - [sc_rollup_challenge_period] levels have passed since when the - commitment was originally published. - *) - val cement_commitment_if_possible : - Node_context.t -> Store.t -> Layer1.head -> unit tzresult Lwt.t - - (** [start ()] only emits the event that the commitment manager - for the rollup node has started. *) - val start : unit -> unit Lwt.t -end diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/components.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/components.ml deleted file mode 100644 index fd412ff4aef56357b420d327fa59d5b6997e68d2..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/components.ml +++ /dev/null @@ -1,47 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* Copyright (c) 2022 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. *) -(* *) -(*****************************************************************************) - -module type S = sig - module PVM : Pvm.S - - module Interpreter : Interpreter.S - - module Commitment : Commitment_sig.S with module PVM = PVM - - module RPC_server : RPC_server.S with module PVM = PVM -end - -module Make (PVM : Pvm.S) : S with module PVM = PVM = struct - module PVM = PVM - module Interpreter = Interpreter.Make (PVM) - module Commitment = Commitment.Make (PVM) - module RPC_server = RPC_server.Make (PVM) -end - -let pvm_of_kind : Protocol.Alpha_context.Sc_rollup.Kind.t -> (module Pvm.S) = - function - | Example_arith -> (module Arith_pvm) - | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/configuration.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/configuration.ml deleted file mode 100644 index af7f25564bbd73ad9522c1b9a1f5256e46146c32..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/configuration.ml +++ /dev/null @@ -1,203 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* Copyright (c) 2022 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 Protocol.Alpha_context - -type t = { - data_dir : string; - sc_rollup_address : Sc_rollup.t; - sc_rollup_node_operator : Signature.Public_key_hash.t; - rpc_addr : string; - rpc_port : int; - fee_parameter : Injection.fee_parameter; -} - -let default_data_dir = - Filename.concat (Sys.getenv "HOME") ".tezos-sc-rollup-node" - -let relative_filename data_dir = Filename.concat data_dir "config.json" - -let filename config = relative_filename config.data_dir - -let default_rpc_addr = "127.0.0.1" - -let default_rpc_port = 8932 - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2794 - the below default values have been copied from - `src/proto_alpha/lib_client/client_proto_args.ml`, but - we need to check whether these values are sensible for the rollup - node. -*) -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 default_force_low_fee = false - -let default_fee_cap = - match Tez.of_string "1.0" with None -> assert false | Some t -> t - -let default_burn_cap = - match Tez.of_string "0" with None -> assert false | Some t -> t - -let default_fee_parameter = - { - Injection.minimal_fees = default_minimal_fees; - minimal_nanotez_per_byte = default_minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit = default_minimal_nanotez_per_gas_unit; - force_low_fee = default_force_low_fee; - fee_cap = default_fee_cap; - burn_cap = default_burn_cap; - } - -let fee_parameter_encoding = - let open Data_encoding in - conv - (fun { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } -> - ( minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap )) - (fun ( minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) -> - { - minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - }) - (obj6 - (dft - "minimal-fees" - ~description:"Exclude operations with lower fees" - Tez.encoding - default_minimal_fees) - (dft - "minimal-nanotez-per-byte" - ~description:"Exclude operations with lower fees per byte" - Plugin.Mempool.nanotez_enc - default_minimal_nanotez_per_byte) - (dft - "minimal-nanotez-per-gas-unit" - ~description:"Exclude operations with lower gas fees" - Plugin.Mempool.nanotez_enc - default_minimal_nanotez_per_gas_unit) - (dft - "force-low-fee" - ~description: - "Don't check that the fee is lower than the estimated default" - bool - default_force_low_fee) - (dft "fee-cap" ~description:"The fee cap" Tez.encoding default_fee_cap) - (dft - "burn-cap" - ~description:"The burn cap" - Tez.encoding - default_burn_cap)) - -let encoding : t Data_encoding.t = - let open Data_encoding in - conv - (fun { - data_dir; - sc_rollup_address; - sc_rollup_node_operator; - rpc_addr; - rpc_port; - fee_parameter; - } -> - ( data_dir, - sc_rollup_address, - sc_rollup_node_operator, - rpc_addr, - rpc_port, - fee_parameter )) - (fun ( data_dir, - sc_rollup_address, - sc_rollup_node_operator, - rpc_addr, - rpc_port, - fee_parameter ) -> - { - data_dir; - sc_rollup_address; - sc_rollup_node_operator; - rpc_addr; - rpc_port; - fee_parameter; - }) - (obj6 - (dft - "data-dir" - ~description:"Location of the data dir" - string - default_data_dir) - (req - "sc-rollup-address" - ~description:"Smart contract rollup address" - Protocol.Alpha_context.Sc_rollup.Address.encoding) - (req - "sc-rollup-node-operator" - ~description: - "Public key hash of the Smart contract rollup node operator" - Signature.Public_key_hash.encoding) - (dft "rpc-addr" ~description:"RPC address" string default_rpc_addr) - (dft "rpc-port" ~description:"RPC port" int16 default_rpc_port) - (dft - "fee-parameter" - ~description:"The fee parameter used when injecting operations in L1" - fee_parameter_encoding - default_fee_parameter)) - -let save config = - let open Lwt_syntax in - let json = Data_encoding.Json.construct encoding config in - let* () = Lwt_utils_unix.create_dir config.data_dir in - Lwt_utils_unix.Json.write_file (filename config) json - -let load ~data_dir = - let open Lwt_result_syntax in - let+ json = Lwt_utils_unix.Json.read_file (relative_filename data_dir) in - Data_encoding.Json.destruct encoding json diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/configuration.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/configuration.mli deleted file mode 100644 index 23bb4576d681ad4a6bbe55911e573a3bd2f29692..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/configuration.mli +++ /dev/null @@ -1,55 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* Copyright (c) 2022 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 t = { - data_dir : string; - sc_rollup_address : Protocol.Alpha_context.Sc_rollup.t; - sc_rollup_node_operator : Signature.Public_key_hash.t; - rpc_addr : string; - rpc_port : int; - fee_parameter : Injection.fee_parameter; -} - -(** [default_data_dir] is the default value for [data_dir]. *) -val default_data_dir : string - -(** [default_rpc_addr] is the default value for [rpc_addr]. *) -val default_rpc_addr : string - -(** [default_rpc_port] is the default value for [rpc_port]. *) -val default_rpc_port : int - -(** [default_fee_parameter] is the default value for [fee_parameter] *) -val default_fee_parameter : Injection.fee_parameter - -(** [filename configuration] returns the [configuration] filename. *) -val filename : t -> string - -(** [save configuration] overwrites [configuration] file. *) -val save : t -> unit tzresult Lwt.t - -(** [load ~data_dir] loads a configuration stored in [data_dir]. *) -val load : data_dir:string -> t tzresult Lwt.t diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/daemon.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/daemon.ml deleted file mode 100644 index 48bfee07de34e920c6c36e4f83a6a3d8d2dafe7a..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/daemon.ml +++ /dev/null @@ -1,254 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 head_state = {head : Layer1.head; finalized : bool; seen_before : bool} - -let emit_head_processing_event - {head = Head {hash; level}; finalized; seen_before} = - Daemon_event.head_processing hash level finalized seen_before - -let emit_heads_not_processed_event head_states = - Lwt_list.iter_s - (fun {head = Head {hash; level}; _} -> - Daemon_event.not_finalized_head hash level) - head_states - -let categorise_heads (node_ctxt : Node_context.t) old_heads new_heads = - (* For each head, determine if it has already been seen before and if it has - been finalized, using the block finality time (for Tenderbake, this - is 2). - *) - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2868 - Handle protocols with non-deterministic finality. *) - let all_heads = old_heads @ new_heads in - let number_of_temporary_heads = - min node_ctxt.block_finality_time (List.length all_heads) - in - - let number_of_new_heads = List.length new_heads in - - let head_states, _, _ = - List.fold_right - (fun head (heads, n, m) -> - ({head; finalized = n <= 0; seen_before = m <= 0} :: heads, n - 1, m - 1)) - all_heads - ([], number_of_temporary_heads, number_of_new_heads) - in - head_states - -module Make (PVM : Pvm.S) = struct - module Components = Components.Make (PVM) - - let process_head node_ctxt store head_state = - (* Because we keep track of finalized heads using transaction finality time, - rather than block finality time, it is possible that heads with the same - level are processed as finalized. Individual modules that process heads - when finalized, such as Commitment, need to take this into account. - *) - let open Lwt_result_syntax in - let {finalized; seen_before; head} = head_state in - let* () = - let*! () = emit_head_processing_event head_state in - if seen_before then return_unit - else - (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/3166 - - If the rollup is subscribed to at least one slot, then the inbox for - this block will be downloaded after lag levels have passed and the - dal slots have been declared available. *) - (* Avoid processing inbox again if it has been processed before for this head *) - let* () = Inbox.process_head node_ctxt store head in - (* Avoid storing and publishing commitments if the head is not final *) - (* Avoid triggering the pvm execution if this has been done before for this head *) - let* () = Components.Interpreter.process_head node_ctxt store head in - Dal_slots_tracker.process_head node_ctxt store head - in - let* () = - if finalized then Components.Commitment.process_head node_ctxt store head - else return_unit - in - (* Publishing a commitment when one is available does not depend on the state of - the current head, but we still need to ensure that the node only published - one commitment per block. *) - let* () = Components.Commitment.publish_commitment node_ctxt store in - let* () = - Components.Commitment.cement_commitment_if_possible node_ctxt store head - in - when_ finalized (fun () -> - let*! () = Layer1.mark_processed_head store head in - return ()) - - (* [on_layer_1_chain_event node_ctxt store chain_event old_heads] processes a - list of heads, coming from either a list of [old_heads] or from the current - [chain_event]. [old_heads] is the list of heads returned by the previous - iteration of [on_layer_1_chain_event] in the [daemonize function]. These are - heads included in the branch currently tracked by the rollup node, and that - have only been partially processed, due to the rollup node not being able - to establish their finality. The function returns a list of heads from the - current branch tracked by the rollup node, whose finality cannot be - established at the time the function is invoked. Those heads will be - processed again at the next iteration of [on_layer_1_chain_event] in the - [daemonize] function. If [chain_event] is a rollback event, then no head - needs to be returned to be included as the rollup node started tracking a - new branch. - *) - let on_layer_1_chain_event node_ctxt store chain_event old_heads = - let open Lwt_result_syntax in - let open Layer1 in - let* () = - (* Get information about the last cemented commitment to determine the - commitment (if any) to publish next. We do this only once per - chain event to avoid spamming the layer1 node. *) - Components.Commitment.sync_last_cemented_commitment_hash_with_level - node_ctxt - store - in - let* non_final_heads = - match chain_event with - | SameBranch {new_head; intermediate_heads} -> - let*! () = - Daemon_event.processing_heads_iteration - old_heads - (intermediate_heads @ [new_head]) - in - let head_states = - categorise_heads - node_ctxt - old_heads - (intermediate_heads @ [new_head]) - in - let* () = List.iter_es (process_head node_ctxt store) head_states in - (* Return new_head to be processed as finalized head if the - next chain event is of type SameBranch. - *) - let non_final_head_states = - List.filter (fun head_state -> not head_state.finalized) head_states - in - let*! () = emit_heads_not_processed_event non_final_head_states in - let non_final_heads = - List.map (fun head_state -> head_state.head) non_final_head_states - in - return non_final_heads - | Rollback {new_head = Layer1.Head {level = new_level; _}} -> - (* The new_head of the rollback event corresponds to a head that - was previously finalized. Heads in `old_heads` that have a level - preceding or equal to `new_level` can now be considered final, - and will be processed as such. `new_level` can now be considered - as such. Heads in `old_heads` whose level is greater than - `new_level` can be safely discarded. - *) - let final_heads, _non_final_heads = - List.partition - (fun head -> - let (Layer1.Head {level; _}) = head in - level <= new_level) - old_heads - in - let+ () = - List.iter_es - (fun head -> - process_head - node_ctxt - store - {head; finalized = true; seen_before = true}) - final_heads - in - [] - in - let*! () = Layer1.processed chain_event in - return non_final_heads - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2895 - Use Lwt_stream.fold_es once it is exposed. *) - let iter_stream stream handle = - let rec go heads = - Lwt.bind (Lwt_stream.get stream) @@ fun tok -> - match tok with - | None -> return_unit - | Some element -> Lwt_result.bind (handle element heads) go - in - go [] - - let daemonize node_ctxt store layer_1_chain_events = - Lwt.no_cancel - @@ iter_stream layer_1_chain_events - @@ on_layer_1_chain_event node_ctxt store - - let install_finalizer store rpc_server heads stopper = - let open Lwt_syntax in - Lwt_exit.register_clean_up_callback ~loc:__LOC__ @@ fun exit_status -> - stopper () ; - let* () = Lwt_stream.closed heads in - let* () = Layer1.shutdown store in - let* () = Components.RPC_server.shutdown rpc_server in - let* () = Store.close store in - let* () = Event.shutdown_node exit_status in - Tezos_base_unix.Internal_event_unix.close () - - let run node_ctxt configuration store = - let open Lwt_result_syntax in - let start () = - let* rpc_server = - Components.RPC_server.start node_ctxt store configuration - in - let* tezos_heads, stopper = - Layer1.start configuration node_ctxt.Node_context.cctxt store - in - let*! () = Inbox.start () in - let*! () = Components.Commitment.start () in - - let _ = install_finalizer store rpc_server tezos_heads stopper in - let*! () = - Event.node_is_ready - ~rpc_addr:configuration.rpc_addr - ~rpc_port:configuration.rpc_port - in - daemonize node_ctxt store tezos_heads - in - start () -end - -let run ~data_dir (cctxt : Protocol_client_context.full) = - let open Lwt_result_syntax in - let*! () = Event.starting_node () in - let* configuration = Configuration.load ~data_dir in - let open Configuration in - let {sc_rollup_address; sc_rollup_node_operator; fee_parameter; _} = - configuration - in - let*! store = Store.load configuration in - let* node_ctxt = - Node_context.init - cctxt - sc_rollup_address - sc_rollup_node_operator - fee_parameter - in - let* _pkh, _pk, _skh = Node_context.get_operator_keys node_ctxt in - (* Check that the public key hash is valid. *) - let module Daemon = Make ((val Components.pvm_of_kind node_ctxt.kind)) in - Daemon.run node_ctxt configuration store diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/daemon_event.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/daemon_event.ml deleted file mode 100644 index 76304ab7172dea9b2846894446b91fcd26171648..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/daemon_event.ml +++ /dev/null @@ -1,88 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; "daemon"] - - let head_processing = - declare_4 - ~section - ~name:"sc_rollup_daemon_process_head" - ~msg: - "Processing: head {hash} at level {level}: finalized? {finalized}, \ - partially processed? {seen_before}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) - ("finalized", Data_encoding.bool) - ("seen_before", Data_encoding.bool) - - let not_finalized_head = - declare_2 - ~section - ~name:"sc_rollup_daemon_not_finalized" - ~msg: - "The following head has only be partially processed - commitments have \ - not been computed: Head {hash} at level {level}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) - - let processing_heads_iteration = - declare_2 - ~section - ~name:"sc_rollup_daemon_processing_heads" - ~msg: - "A new iteration of process_heads has been triggered: processing heads \ - from level {from} to level {to}" - ~level:Notice - ("from", Data_encoding.int32) - ("to", Data_encoding.int32) -end - -let head_processing hash level finalized seen_before = - Simple.(emit head_processing (hash, level, finalized, seen_before)) - -let not_finalized_head hash level = - Simple.(emit not_finalized_head (hash, level)) - -let processing_heads_iteration old_heads new_heads = - let maybe_level = Option.map (fun (Layer1.Head {level; _}) -> level) in - let from_level = - match maybe_level @@ List.hd old_heads with - | None -> maybe_level @@ List.hd new_heads - | Some level -> Some level - in - let to_level = - match maybe_level @@ List.last_opt new_heads with - | None -> maybe_level @@ List.hd old_heads - | Some level -> Some level - in - match (from_level, to_level) with - | Some from_level, Some to_level -> - Simple.(emit processing_heads_iteration (from_level, to_level)) - | _ -> Lwt.return_unit diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/daemon_event.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/daemon_event.mli deleted file mode 100644 index d0927a06d11f6d00a34bd45b2a9a8ebdde9abed0..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/daemon_event.mli +++ /dev/null @@ -1,44 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 functions that emit the events used by the smart - contract rollup node daemon (see {!Daemon}). *) - -(** [head_processing hash level finalized seen_before] emits the event that the - block of the given [hash] and at the given [level] is being processed, and - whether it is [finalized] and has been [seen_before]. *) -val head_processing : Block_hash.t -> int32 -> bool -> bool -> unit Lwt.t - -(** [not_finalized_head hash level] emits the event that the block of the given - [hash] and at the given [level] is being processed but has not been - finalized yet by the layer 1 consensus algorithm. *) -val not_finalized_head : Block_hash.t -> int32 -> unit Lwt.t - -(** [processing_heads_iteration old_heads new_heads] emits the event that a new - iteration of processing the heads has been triggered, from the level of the - oldest head to the level of the most recent head between the [old_heads] and - the [new_heads]. *) -val processing_heads_iteration : - Layer1.head list -> Layer1.head list -> unit Lwt.t diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/dal_slots_tracker.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/dal_slots_tracker.ml deleted file mode 100644 index d230c7c78431827370844ed7e45479d443842a28..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/dal_slots_tracker.ml +++ /dev/null @@ -1,46 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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) - -let get_slot_subscriptions cctxt head rollup = - let open Lwt_result_syntax in - let*? level = Environment.wrap_tzresult @@ Raw_level.of_int32 (snd head) in - Plugin.RPC.Sc_rollup.dal_slot_subscriptions - cctxt - (cctxt#chain, cctxt#block) - rollup - level - -let process_head Node_context.{cctxt; rollup_address; _} store - Layer1.(Head {level; hash = head_hash}) = - let open Lwt_result_syntax in - let* res = get_slot_subscriptions cctxt (head_hash, level) rollup_address in - let*! () = Store.Dal_slot_subscriptions.add store head_hash res in - return_unit - -let start () = Lwt.return () diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/dal_slots_tracker.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/dal_slots_tracker.mli deleted file mode 100644 index 0f1b92f74c3a4418243851759a92630a6cdce242..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/dal_slots_tracker.mli +++ /dev/null @@ -1,41 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 rollup node keeps the list of dal slots to which the rollup is - subscribed to for each block it needs to process. This is to determine - whether the inbox for a given block will need to be retrieved from the - block operations, or from the data availability layer after lag levels - have passed and the slot for the block has been declared available. - - The state of subscribed slots per block is persistent. -*) - -(** [process_head node_ctxt store head] fetches the slot indices to which the rollup is - subscribed to, and stores them. *) -val process_head : - Node_context.t -> Store.t -> Layer1.head -> unit tzresult Lwt.t - -(** [start ()] initializes the Dal_slot_tracker to track the dal slot subscriptions. *) -val start : unit -> unit Lwt.t diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/dune b/src/proto_014_PtKathma/bin_sc_rollup_node/dune deleted file mode 100644 index dedeab78fee0a0c9cbd7955efe5fbb877a28cc92..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/dune +++ /dev/null @@ -1,57 +0,0 @@ -; This file was automatically generated, do not edit. -; Edit file manifest/main.ml instead. - -(executable - (name main_sc_rollup_node_014_PtKathma) - (public_name octez-sc-rollup-node-PtKathma) - (package octez-sc-rollup-node-PtKathma) - (instrumentation (backend bisect_ppx)) - (libraries - tezos-base - tezos-clic - tezos-client-commands - tezos-stdlib-unix - tezos-client-base - tezos-client-base-unix - tezos-client-014-PtKathma - tezos-context.encoding - tezos-context.helpers - tezos-protocol-014-PtKathma - tezos-protocol-plugin-014-PtKathma - tezos-protocol-014-PtKathma.parameters - tezos-rpc - tezos-rpc-http - tezos-rpc-http-server - tezos_dal_node_services - tezos-shell-services - tezos-sc-rollup-014-PtKathma - tezos_layer2_store - data-encoding - irmin-pack - irmin-pack.unix - irmin - ringo - ringo-lwt - tezos-injector-014-PtKathma - tezos-scoru-wasm) - (link_flags - (:standard) - (:include %{workspace_root}/static-link-flags.sexp)) - (flags - (:standard) - -open Tezos_base.TzPervasives - -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals - -open Tezos_clic - -open Tezos_client_commands - -open Tezos_stdlib_unix - -open Tezos_client_base - -open Tezos_client_base_unix - -open Tezos_client_014_PtKathma - -open Tezos_protocol_014_PtKathma - -open Tezos_protocol_plugin_014_PtKathma - -open Tezos_protocol_014_PtKathma_parameters - -open Tezos_rpc - -open Tezos_shell_services - -open Tezos_sc_rollup_014_PtKathma - -open Tezos_layer2_store - -open Tezos_injector_014_PtKathma)) diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/event.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/event.ml deleted file mode 100644 index 53588fecec3e7508d3dd921345af0d729d650a72..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/event.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. *) -(* *) -(*****************************************************************************) - -module Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"] - - let starting_node = - declare_0 - ~section - ~name:"starting_sc_rollup_node" - ~msg:"Starting the smart contract rollup node" - ~level:Notice - () - - let shutdown_node = - declare_1 - ~section - ~name:"stopping_sc_rollup_node" - ~msg:"Stopping the smart contract rollup node" - ~level:Notice - ("exit_status", Data_encoding.int8) - - let node_is_ready = - declare_2 - ~section - ~name:"sc_rollup_node_is_ready" - ~msg:"The smart contract rollup node is listening to {addr}:{port}" - ~level:Notice - ("addr", Data_encoding.string) - ("port", Data_encoding.uint16) - - let rollup_exists = - declare_2 - ~section - ~name:"sc_rollup_node_knows_its_rollup" - ~msg: - "The smart contract rollup node is interacting with rollup {addr} of \ - kind {kind}" - ~level:Notice - ("addr", Protocol.Alpha_context.Sc_rollup.Address.encoding) - ("kind", Data_encoding.string) -end - -let starting_node = Simple.(emit starting_node) - -let shutdown_node exit_status = Simple.(emit shutdown_node exit_status) - -let node_is_ready ~rpc_addr ~rpc_port = - Simple.(emit node_is_ready (rpc_addr, rpc_port)) - -let rollup_exists ~addr ~kind = - let kind = Protocol.Alpha_context.Sc_rollup.Kind.name_of kind in - Simple.(emit rollup_exists (addr, kind)) diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/event.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/event.mli deleted file mode 100644 index 953633772447586ca510ed2956be65515e844105..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/event.mli +++ /dev/null @@ -1,42 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 functions that emit the events used when the smart - contract rollup node is running (see {!Daemon}). *) - -open Protocol.Alpha_context - -val starting_node : unit -> unit Lwt.t - -val node_is_ready : rpc_addr:string -> rpc_port:int -> unit Lwt.t - -(** [rollup_exists addr kind] emits the event that the smart contract rollup - node is interacting with the rollup at address [addr] and of the given - [kind]. *) -val rollup_exists : addr:Sc_rollup.t -> kind:Sc_rollup.Kind.t -> unit Lwt.t - -(** [shutdown_node exit_status] emits the event that the smart contract rollup - node is stopping with exit status [exit_status]. *) -val shutdown_node : int -> unit Lwt.t diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/inbox.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/inbox.ml deleted file mode 100644 index a51e99ba6f721d78c27500ada5370279a150fce6..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/inbox.ml +++ /dev/null @@ -1,133 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 Constants will be shadowed by Alpha_context.Constansts - once we open Alpha_context, hence we we alias it to Rollup_node_constants -*) -open Protocol -open Alpha_context -module Block_services = Block_services.Make (Protocol) (Protocol) - -let lift = Lwt.map Environment.wrap_tzresult - -let head_processing_failure e = - Format.eprintf - "Error during head processing: @[%a@]" - Error_monad.(TzTrace.pp_print_top pp) - e ; - Lwt_exit.exit_and_raise 1 - -module State = struct - let add_messages = Store.Messages.add - - let add_inbox = Store.Inboxes.add - - let add_history = Store.Histories.add - - let inbox_of_hash node_ctxt store block_hash = - let open Lwt_syntax in - let open Node_context in - let+ possible_inbox = Store.Inboxes.find store block_hash in - match possible_inbox with - | None -> - (* We won't find inboxes for blocks before the rollup origination level. - Fortunately this case will only ever be called once when dealing with - the rollup origination block. After that we would always find an - inbox. *) - Sc_rollup.Inbox.empty node_ctxt.rollup_address node_ctxt.initial_level - | Some inbox -> inbox - - let history_of_hash store block_hash = - Store.Histories.find_with_default store block_hash ~on_default:(fun () -> - Store.Inbox.history_at_genesis ~bound:(Int64.of_int 60000)) - - let get_message_tree = Store.MessageTrees.get - - let set_message_tree = Store.MessageTrees.set -end - -let get_messages cctxt head rollup = - let open Lwt_result_syntax in - let open Block_services in - let+ operations = - Operations.operations cctxt ~chain:`Main ~block:(`Level (snd head)) () - in - let is_add_message = function - | Contents - (Manager_operation - {operation = Sc_rollup_add_messages {rollup = rollup'; messages}; _}) - when Sc_rollup.Address.(rollup' = rollup) -> - messages - | _ -> [] - in - let process_contents {protocol_data = Operation_data {contents; _}; _} = - let operations = Operation.to_list (Contents_list contents) in - List.concat_map is_add_message operations - in - let process_operations operations = - List.concat_map process_contents operations - in - List.concat_map process_operations operations - -let process_head Node_context.({cctxt; rollup_address; _} as node_ctxt) store - Layer1.(Head {level; hash = head_hash} as head) = - let open Lwt_result_syntax in - let*! res = get_messages cctxt (head_hash, level) rollup_address in - match res with - | Error e -> head_processing_failure e - | Ok messages -> - let*! () = - Inbox_event.get_messages head_hash level (List.length messages) - in - let*! () = State.add_messages store head_hash messages in - (* - - We compute the inbox of this block using the inbox of its - predecessor. That way, the computation of inboxes is robust - to chain reorganization. - - *) - let*! predecessor = Layer1.predecessor store head in - let*! inbox = State.inbox_of_hash node_ctxt store predecessor in - lift - @@ let*! history = State.history_of_hash store predecessor in - let*! messages_tree = State.get_message_tree store predecessor in - let*? level = Raw_level.of_int32 level in - let* messages_tree, history, inbox = - Store.Inbox.add_external_messages - history - inbox - level - messages - messages_tree - in - let*! () = State.set_message_tree store head_hash messages_tree in - let*! () = State.add_inbox store head_hash inbox in - let*! () = State.add_history store head_hash history in - return_unit - -let inbox_of_hash = State.inbox_of_hash - -let start () = Inbox_event.starting () diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/inbox.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/inbox.mli deleted file mode 100644 index 162ebf02e44fbb422b2fecd88e187637ea2ffced..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/inbox.mli +++ /dev/null @@ -1,54 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 rollup node maintains an inbox of incoming messages. - - The incoming messages for a rollup are published on the layer 1. To - maintain the state of its inbox, a rollup node retrieves these - messages each time the tezos blockchain is updated. - - The inbox state is persistent. - -*) -open Protocol - -(** [process_head node_ctxt store head] changes the state of the inbox to react to - [head]. In particular, this process requests the tezos node - through the context client [node_ctxt.cctxt] to retrieve the messages published - at the level indicated by [head]. *) - -val process_head : - Node_context.t -> Store.t -> Layer1.head -> unit tzresult Lwt.t - -(** [inbox_of_hash node_ctxt store block_hash] returns the rollup inbox at the end of the - given validation of [block_hash]. *) -val inbox_of_hash : - Node_context.t -> - Store.t -> - Block_hash.t -> - Alpha_context.Sc_rollup.Inbox.t Lwt.t - -(** [start ()] initializes the inbox to track the messages being published. *) -val start : unit -> unit Lwt.t diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/inbox_event.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/inbox_event.ml deleted file mode 100644 index 36464fa0453fc72de9d72ddbba770f2ff4f39937..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/inbox_event.ml +++ /dev/null @@ -1,65 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; "inbox"] - - let starting = - declare_0 - ~section - ~name:"sc_rollup_node_inbox_starting" - ~msg:"Starting inbox tracker of the smart contract rollup node" - ~level:Notice - () - - let stopping = - declare_0 - ~section - ~name:"sc_rollup_node_inbox_stopping" - ~msg:"Stopping inbox tracker of the smart contract rollup node" - ~level:Notice - () - - let get_messages = - declare_3 - ~section - ~name:"sc_rollup_node_layer_1_get_messages" - ~msg: - "Fetching {number_of_messages} messages from block {hash} at level \ - {level}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) - ("number_of_messages", Data_encoding.int32) -end - -let starting = Simple.(emit starting) - -let stopping = Simple.(emit stopping) - -let get_messages hash level number_of_messages = - Simple.(emit get_messages (hash, level, Int32.of_int number_of_messages)) diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/inbox_event.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/inbox_event.mli deleted file mode 100644 index 72a3b8200880eadedfe867fec3747d53a9e7d5be..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/inbox_event.mli +++ /dev/null @@ -1,35 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 functions that emit the events used by the rollup node - for incoming messages (see {!Inbox}). *) - -val starting : unit -> unit Lwt.t - -val stopping : unit -> unit Lwt.t - -(** [get_messages hash level n] emits the event that [n] messages are being - fetched from the block of the given [hash] at the given [level]. *) -val get_messages : Block_hash.t -> int32 -> int -> unit Lwt.t diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/interpreter.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/interpreter.ml deleted file mode 100644 index a1a9cb4a25c57759e391dec6b72d350f4dc439df..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/interpreter.ml +++ /dev/null @@ -1,135 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 Inbox = Store.Inbox - -module type S = sig - (** [process_head node_ctxt store head] interprets the messages associated - with a [head] from a chain [event]. This requires the inbox to be updated - beforehand. *) - val process_head : - Node_context.t -> Store.t -> Layer1.head -> unit tzresult Lwt.t -end - -module Make (PVM : Pvm.S) : S = struct - module PVM = PVM - - (** [eval_until_input state] advances a PVM [state] until it wants more inputs. *) - let eval_until_input state = - let open Lwt_syntax in - let rec go state = - let* input_request = PVM.is_input_state state in - match input_request with - | No_input_required -> - let* next_state = PVM.eval state in - go next_state - | _ -> return state - in - go state - - (** [feed_input state input] feeds [input] to the PVM in order to advance [state] to the next step - that requires an input. *) - let feed_input state input = - let open Lwt_syntax in - let* state = eval_until_input state in - let* state = PVM.set_input input state in - let* state = PVM.eval state in - let* state = eval_until_input state in - return state - - (** [transition_pvm node_ctxt store predecessor_hash hash] runs a PVM at the previous state from block - [predecessor_hash] by consuming as many messages as possible from block [hash]. *) - let transition_pvm node_ctxt store predecessor_hash hash = - let open Node_context in - let open Lwt_result_syntax in - (* Retrieve the previous PVM state from store. *) - let*! predecessor_state = Store.PVMState.find store predecessor_hash in - let* predecessor_state = - match predecessor_state with - | None -> - (* The predecessor is before the origination. - Here we use an RPC to get the boot sector instead of doing this - before and packing it into the [node_ctxt] because the bootsector - might be very large and we don't want to keep that in memory for - ever. - *) - let* boot_sector = - Plugin.RPC.Sc_rollup.boot_sector - node_ctxt.cctxt - (node_ctxt.cctxt#chain, node_ctxt.cctxt#block) - node_ctxt.rollup_address - in - let*! initial_state = PVM.initial_state store boot_sector in - return initial_state - | Some predecessor_state -> return predecessor_state - in - - (* Obtain inbox and its messages for this block. *) - let*! inbox = Store.Inboxes.get store hash in - let inbox_level = Inbox.inbox_level inbox in - let*! messages = Store.Messages.get store hash in - - (* Iterate the PVM state with all the messages for this level. *) - let*! state = - List.fold_left_i_s - (fun message_counter state payload -> - let input = - Sc_rollup. - {inbox_level; message_counter = Z.of_int message_counter; payload} - in - feed_input state input) - predecessor_state - messages - in - - (* Write final state to store. *) - let*! () = Store.PVMState.set store hash state in - - (* Compute extra information about the state. *) - let*! initial_tick = PVM.get_tick predecessor_state in - let*! last_tick = PVM.get_tick state in - (* TODO: #2717 - The number of ticks should not be an arbitrarily-sized integer. - *) - let num_ticks = Sc_rollup.Tick.distance initial_tick last_tick in - (* TODO: #2717 - The length of messages here can potentially overflow the [int] returned from [List.length]. - *) - let num_messages = Z.of_int (List.length messages) in - let*! () = Store.StateInfo.add store hash {num_messages; num_ticks} in - - (* Produce events. *) - let*! () = Interpreter_event.transitioned_pvm state num_messages in - - return_unit - - (** [process_head node_ctxt store head] runs the PVM for the given head. *) - let process_head node_ctxt store (Layer1.Head {hash; _} as head) = - let open Lwt_result_syntax in - let*! predecessor_hash = Layer1.predecessor store head in - transition_pvm node_ctxt store predecessor_hash hash -end diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/interpreter_event.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/interpreter_event.ml deleted file mode 100644 index d177dd810f3a434b18e9d3d9530a52c7894720b9..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/interpreter_event.ml +++ /dev/null @@ -1,51 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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.Sc_rollup - -module Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; "interpreter"] - - let transitioned_pvm = - declare_3 - ~section - ~name:"sc_rollup_node_interpreter_transitioned_pvm" - ~msg: - "Transitioned PVM to {state_hash} at tick {ticks} with {num_messages} \ - messages" - ~level:Notice - ("state_hash", State_hash.encoding) - ("ticks", Tick.encoding) - ("num_messages", Data_encoding.z) -end - -let transitioned_pvm state num_messages = - let open Lwt_syntax in - (* TODO (#3094): is this code path taken for Wasm_2_0_0_pvm. Do we need to abstract? *) - let* hash = Arith_pvm.state_hash state in - let* ticks = Arith_pvm.get_tick state in - Simple.(emit transitioned_pvm (hash, ticks, num_messages)) diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/interpreter_event.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/interpreter_event.mli deleted file mode 100644 index 2c7cd5106921ca8110d7664730d8ecd700f183a2..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/interpreter_event.mli +++ /dev/null @@ -1,31 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 functions that emit the events used when running a PVM - transition (see {!Interpreter}). *) - -(** [transition_pvm hash n] emits the event that a PVM transition is leading to - the state of the given [hash] by processing [n] messages. *) -val transitioned_pvm : Arith_pvm.state -> Z.t -> unit Lwt.t diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/layer1.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/layer1.ml deleted file mode 100644 index ee02f32af2899e053e252d50d03d8e1e57efecc0..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/layer1.ml +++ /dev/null @@ -1,403 +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 Configuration -open Protocol.Alpha_context -open Plugin - -(** - - Errors - ====== - -*) -let synchronization_failure e = - Format.eprintf - "Error during synchronization: @[%a@]" - Error_monad.(TzTrace.pp_print_top pp) - e ; - Lwt_exit.exit_and_raise 1 - -(** - - State - ===== - -*) - -type block_hash = Block_hash.t - -type block = Block of {predecessor : block_hash; level : int32} - -let block_encoding = - Data_encoding.( - conv - (fun (Block {predecessor; level}) -> (predecessor, level)) - (fun (predecessor, level) -> Block {predecessor; level}) - (obj2 - (req "predecessor" Block_hash.encoding) - (req "level" Data_encoding.int32))) - -type head = Head of {hash : block_hash; level : int32} - -let head_encoding = - Data_encoding.( - conv - (fun (Head {hash; level}) -> (hash, level)) - (fun (hash, level) -> Head {hash; level}) - (obj2 (req "hash" Block_hash.encoding) (req "level" Data_encoding.int32))) - -module State = struct - let reorganization_window_length = 10 - - module Store = struct - module Blocks = Store.Make_append_only_map (struct - let path = ["tezos"; "blocks"] - - let keep_last_n_entries_in_memory = reorganization_window_length - - type key = block_hash - - let string_of_key = Block_hash.to_b58check - - type value = block - - let value_encoding = block_encoding - end) - - module Head = Store.Make_mutable_value (struct - let path = ["tezos"; "head"] - - type value = head - - let value_encoding = head_encoding - end) - - module ProcessedHashes = Store.Make_append_only_map (struct - let path = ["tezos"; "processed_blocks"] - - let keep_last_n_entries_in_memory = reorganization_window_length - - type key = block_hash - - let string_of_key = Block_hash.to_b58check - - type value = unit - - let value_encoding = Data_encoding.unit - end) - - module LastProcessedHead = Store.Make_mutable_value (struct - let path = ["tezos"; "processed_head"] - - type value = head - - let value_encoding = head_encoding - end) - end - - let last_seen_head = Store.Head.find - - let set_new_head = Store.Head.set - - let store_block = Store.Blocks.add - - let block_of_hash = Store.Blocks.get - - let mark_processed_head store (Head {hash; _} as head) = - let open Lwt_syntax in - let* () = Store.ProcessedHashes.add store hash () in - Store.LastProcessedHead.set store head - - let is_processed = Store.ProcessedHashes.mem - - let last_processed_head = Store.LastProcessedHead.find -end - -(** - - Chain events - ============ - -*) - -type chain_event = - | SameBranch of {new_head : head; intermediate_heads : head list} - | Rollback of {new_head : head} - -let same_branch new_head intermediate_heads = - SameBranch {new_head; intermediate_heads} - -let rollback new_head = Rollback {new_head} - -(** - - Helpers - ======= - -*) - -let genesis_hash = - Block_hash.of_b58check_exn - "BLockGenesisGenesisGenesisGenesisGenesisf79b5d1CoW2" - -(** [blocks_of_heads base heads] given a list of successive heads - connected to [base], returns an associative list mapping block hash - to block. This list is only used for traversal, not lookup. The - newer blocks come first in that list. *) -let blocks_of_heads base heads = - let rec aux predecessor accu = function - | [] -> accu - | Head {hash; level} :: xs -> - let block = Block {predecessor; level} in - aux hash ((hash, block) :: accu) xs - in - aux base [] heads - -(** [store_chain_event event] updates the persistent state to take a - chain event into account. *) -let store_chain_event store base = - let open Lwt_syntax in - function - | SameBranch {new_head = Head {hash; level} as head; intermediate_heads} -> - let* () = Layer1_event.setting_new_head hash level in - let* () = State.set_new_head store head in - blocks_of_heads base (intermediate_heads @ [head]) - |> List.iter_s (fun (hash, block) -> State.store_block store hash block) - | Rollback {new_head = Head {hash; level} as base} -> - let* () = Layer1_event.rollback hash level in - State.set_new_head store base - -(** [predecessors_of_blocks hashes] given a list of successive hashes, - returns an associative list that associates a hash to its - predecessor in this list. *) -let predecessors_of_blocks hashes = - let rec aux next = function [] -> [] | x :: xs -> (next, x) :: aux x xs in - match hashes with [] -> [] | x :: xs -> aux x xs - -(** [get_predecessor block_hash] returns the predecessor block hash of - some [block_hash] through an RPC to the Tezos node. To limit the - number of RPCs, this information is requested for a batch of hashes - and cached locally. *) -let get_predecessor = - let max_cached = 1023 and max_read = 8 in - let (module HMF : Ringo.MAP_MAKER) = - Ringo.(map_maker ~replacement:FIFO ~overflow:Strong ~accounting:Precise) - in - let module HM = HMF (Block_hash) in - let cache = HM.create max_cached in - fun cctxt (chain : Tezos_shell_services.Chain_services.chain) ancestor -> - match HM.find_opt cache ancestor with - | Some pred -> Lwt.return (Some pred) - | None -> ( - Tezos_shell_services.Chain_services.Blocks.list - cctxt - ~chain - ~heads:[ancestor] - ~length:max_read - () - >>= function - | Error e -> synchronization_failure e - | Ok blocks -> ( - match blocks with - | [ancestors] -> ( - List.iter - (fun (h, p) -> HM.replace cache h p) - (predecessors_of_blocks ancestors) ; - match HM.find_opt cache ancestor with - | None -> - (* We have just updated the cache with that information. *) - assert false - | Some predecessor -> Lwt.return (Some predecessor)) - | _ -> Lwt.return None)) - -let get_predecessor_head cctxt chain (Head {level; hash}) = - let open Lwt_syntax in - let level = Int32.pred level in - let+ hash' = get_predecessor cctxt chain hash in - Option.map (fun hash' -> Head {level; hash = hash'}) hash' - -(** [catch_up cctxt chain last_seen_head predecessor new_head] - classifies the [new_head] (with some given [predecessor]) in two - distinct categories: - - - If [new_head] has an ancestor which is the [last_seen_head], - returns [SameBranch { new_head; intermediate_heads }] where - [intermediate_heads] are the blocks between [last_seen_head] and - [new_head] in order of increasing levels. - - - If [new_head] has an ancestor that is an ancestor [base] of - [last_seen_head] then returns [Rollback { new_head }]. - - This function also returns the block hash to which the current - branch is rooted. -*) -let catch_up cctxt store chain last_seen_head new_head = - let (Head {hash; _}) = last_seen_head in - - (* [heads] is the list of intermediate heads between - the predecessor of [ancestor] and the [new_head]. [level] - is the level of [ancestor]. *) - let rec aux heads (Head {hash = ancestor_hash; level} as ancestor) = - if Block_hash.equal ancestor_hash hash then - (* We have reconnected to the last seen head. *) - Lwt.return (ancestor_hash, [same_branch new_head heads]) - else - State.is_processed store ancestor_hash >>= function - | true -> - (* We have reconnected to a previously known head. - [new_head] and [last_seen_head] are not the same branch. *) - Lwt.return - (ancestor_hash, [rollback ancestor; same_branch new_head heads]) - | false -> ( - (* We have never seen this head. *) - let heads = ancestor :: heads in - get_predecessor cctxt chain ancestor_hash >>= function - | Some ancestor' when Block_hash.(ancestor_hash <> ancestor') -> - aux heads (Head {level = Int32.pred level; hash = ancestor'}) - | _ -> - (* We have reconnected with the genesis head and it was - unknown until now. *) - Lwt.return (ancestor_hash, [same_branch new_head heads])) - in - get_predecessor_head cctxt chain new_head >>= function - | None -> - (* [new_head] is the genesis head. It is not new. *) - Lwt.return (genesis_hash, []) - | Some predecessor -> aux [] predecessor - -let chain_events cctxt store chain = - let open Lwt_result_syntax in - let on_head (hash, (block_header : Tezos_base.Block_header.t)) = - let level = block_header.shell.level in - let new_head = Head {hash; level} in - let*! last_seen_head = State.last_seen_head store in - let last_seen_head = - match last_seen_head with - | None -> Head {hash = genesis_hash; level = 0l} - | Some last_seen_head -> last_seen_head - in - let*! base, events = catch_up cctxt store chain last_seen_head new_head in - let*! () = List.iter_s (store_chain_event store base) events in - Lwt.return events - in - let+ heads, stopper = - Tezos_shell_services.Monitor_services.heads cctxt chain - in - (Lwt_stream.map_list_s on_head heads, stopper) - -let check_sc_rollup_address_exists sc_rollup_address - (cctxt : Protocol_client_context.full) = - let open Lwt_result_syntax in - let* kind = - RPC.Sc_rollup.kind cctxt (cctxt#chain, cctxt#block) sc_rollup_address () - in - let*! () = Event.rollup_exists ~addr:sc_rollup_address ~kind in - return_unit - -type info = {origination_level : int32} - -let gather_info (cctxt : Protocol_client_context.full) sc_rollup_address = - let open Lwt_result_syntax in - let* origination_level = - RPC.Sc_rollup.initial_level - cctxt - (cctxt#chain, cctxt#block) - sc_rollup_address - in - return {origination_level = Raw_level.to_int32 origination_level} - -(** [discard_pre_origination_blocks info chain_events] filters [chain_events] in order to - discard all heads that occur before the SC rollup origination. *) -let discard_pre_origination_blocks info chain_events = - let at_or_after_origination event = - match event with - | SameBranch {new_head = Head {level; _} as new_head; intermediate_heads} - when level >= info.origination_level -> - let intermediate_heads = - List.filter - (fun (Head {level; _}) -> level >= info.origination_level) - intermediate_heads - in - Some (SameBranch {new_head; intermediate_heads}) - | Rollback {new_head = Head {level; _}} when level >= info.origination_level - -> - Some event - | _ -> None - in - Lwt_stream.filter_map at_or_after_origination chain_events - -let start configuration (cctxt : Protocol_client_context.full) store = - let open Lwt_result_syntax in - let*! () = Layer1_event.starting () in - let* () = - check_sc_rollup_address_exists configuration.sc_rollup_address cctxt - in - let* event_stream, stopper = chain_events cctxt store `Main in - let* info = gather_info cctxt configuration.sc_rollup_address in - return (discard_pre_origination_blocks info event_stream, stopper) - -let current_head_hash store = - let open Lwt_syntax in - let+ head = State.last_seen_head store in - Option.map (fun (Head {hash; _}) -> hash) head - -let current_level store = - let open Lwt_syntax in - let+ head = State.last_seen_head store in - Option.map (fun (Head {level; _}) -> level) head - -let predecessor store (Head {hash; _}) = - let open Lwt_syntax in - let+ (Block {predecessor; _}) = State.block_of_hash store hash in - predecessor - -let processed_head (Head {hash; level}) = - Layer1_event.new_head_processed hash level - -let processed = function - | SameBranch {new_head; intermediate_heads} -> - List.iter_s processed_head (intermediate_heads @ [new_head]) - | Rollback {new_head} -> processed_head new_head - -let mark_processed_head store head = State.mark_processed_head store head - -(* We forget about the last seen heads that are not processed so that - the rollup node can process them when restarted. Notice that this - does prevent skipping heads when the node is interrupted in a bad - way. *) - -(* FIXME: https://gitlab.com/tezos/tezos/-/issues/3205 - - More generally, The rollup node should be able to restart properly - after an abnormal interruption at every point of its process. - Currently, the state is not persistent enough and the processing is - not idempotent enough to achieve that property. *) -let shutdown store = - let open Lwt_syntax in - let* last_processed_head = State.last_processed_head store in - match last_processed_head with - | None -> return_unit - | Some head -> State.set_new_head store head diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/layer1.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/layer1.mli deleted file mode 100644 index 8ea49d73bcde3c5485be795557335bea38cc813d..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/layer1.mli +++ /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. *) -(* *) -(*****************************************************************************) - -(** This module maintains information about the layer 1 chain. - - This module follows the evolution of the layer 1 chain by - subscribing to the head monitoring RPC offered by the Tezos node. - - When started, it provides a stream of events that can be used to be - informed when the head of the layer 1 has changed or when a chain - reorganization occurred. - -*) -type head = Head of {hash : Block_hash.t; level : int32} - -val head_encoding : head Data_encoding.t - -type chain_event = - | SameBranch of {new_head : head; intermediate_heads : head list} - (** The [new_head] follows the current branch. [intermediate_heads] - have been included since the previous synchronization with Tezos - node. *) - | Rollback of {new_head : head} - (** A chain reorganization occurred since the previous - synchronization. The rollback set [new_head] to an old block. *) - -(** [start configuration cctxt store] returns a stream of [chain_event] - obtained from the monitoring of the Tezos node set up by the client - [cctxt]. The layer 1 state is stored in the data directory declared - in [configuration]. *) -val start : - Configuration.t -> - Protocol_client_context.full -> - Store.t -> - (chain_event Lwt_stream.t * RPC_context.stopper) tzresult Lwt.t - -(** [current_head_hash store] is the current hash of the head of the - Tezos chain as far as the smart-contract rollup node knows from the - latest synchronization. Returns [None] if no synchronization has - ever been made. *) -val current_head_hash : Store.t -> Block_hash.t option Lwt.t - -(** [current_level store] is the current level of the Tezos chain as far - as the smart-contract rollup node knows from the latest - synchronization. Returns [None] if no synchronization has ever been - made. *) -val current_level : Store.t -> int32 option Lwt.t - -(** [predecessor store head] returns the hash of the head's predecessor block] *) -val predecessor : Store.t -> head -> Block_hash.t Lwt.t - -(** [genesis_hash] is the hash of the genesis block of the chain. *) -val genesis_hash : Block_hash.t - -(** [processed chain_event] emits a log event to officialize the - processing of some layer 1 [chain_event]. *) -val processed : chain_event -> unit Lwt.t - -(** [mark_process_head store head] remembers that the [head] - is processed. The system should not have to come back to - it. *) -val mark_processed_head : Store.t -> head -> unit Lwt.t - -(** [shutdown store] properly shut the layer 1 down. *) -val shutdown : Store.t -> unit Lwt.t diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/layer1_event.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/layer1_event.ml deleted file mode 100644 index 3559bfd6ad38c0e4388361fee299e67d216d18a6..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/layer1_event.ml +++ /dev/null @@ -1,98 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; "layer_1"] - - let starting = - declare_0 - ~section - ~name:"sc_rollup_node_layer_1_starting" - ~msg:"Starting layer 1 tracker of the smart contract rollup node" - ~level:Notice - () - - let stopping = - declare_0 - ~section - ~name:"sc_rollup_node_layer_1_stopping" - ~msg:"Stopping layer 1 tracker of the smart contract rollup node" - ~level:Notice - () - - let setting_new_head = - declare_2 - ~section - ~name:"sc_rollup_node_layer_1_new_head" - ~msg:"Setting layer 1 head to {hash} at level {level}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) - - let rollback = - declare_2 - ~section - ~name:"sc_rollup_node_layer_1_rollback" - ~msg:"Rolling back layer 1 head to {hash} at level {level}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) - - let reacting_to_reorganization = - declare_2 - ~section - ~name:"sc_rollup_node_layer_1_reorganization" - ~msg: - "Reacting to layer 1 reorganization: rollback to {rollback_hash}, \ - process {new_blocks}" - ~level:Notice - ("rollback_hash", Block_hash.encoding) - ("new_blocks", Data_encoding.list Block_hash.encoding) - - let new_head_processed = - declare_2 - ~section - ~name:"sc_rollup_node_layer_1_new_head_processed" - ~msg:"Finished processing layer 1 head {hash} at level {level}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) -end - -let starting = Simple.(emit starting) - -let stopping = Simple.(emit stopping) - -let setting_new_head hash level = Simple.(emit setting_new_head (hash, level)) - -let new_head_processed hash level = - Simple.(emit new_head_processed (hash, level)) - -let reacting_to_reorganization h hs = - Simple.(emit reacting_to_reorganization (h, hs)) - -let rollback h hs = Simple.(emit rollback (h, hs)) diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/layer1_event.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/layer1_event.mli deleted file mode 100644 index 3531bfd1200321f3a03d69b0d1ae1a5551caf076..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/layer1_event.mli +++ /dev/null @@ -1,48 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 functions that emit the events used by the layer 1 chain - (see {!Layer}). *) - -val starting : unit -> unit Lwt.t - -val stopping : unit -> unit Lwt.t - -(** [rollback hash level] emits the event that the layer 1 head is rolling back - to the block of the given [hash] and at the given [level]. *) -val rollback : Block_hash.t -> int32 -> unit Lwt.t - -(** [setting_new_head hash level] emits the event that the layer 1 head is set - to the block of the given [hash] and at the given [level]. *) -val setting_new_head : Block_hash.t -> int32 -> unit Lwt.t - -(** [new_head_processed hash level] emits the event that the layer 1 head of the - given [hash] and at the given [level] is finished processing. *) -val new_head_processed : Block_hash.t -> int32 -> unit Lwt.t - -(** [reacting_to_reorganization rollbacked_block new_blocks] emits the event - that the rollup node is rolling back to the block of hash [rollbacked_block] - and will be processing the [new_blocks] due to a layer 1 reorganization. *) -val reacting_to_reorganization : Block_hash.t -> Block_hash.t list -> unit Lwt.t diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/main_sc_rollup_node_014_PtKathma.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/main_sc_rollup_node_014_PtKathma.ml deleted file mode 100644 index e51e48107ee90e1a656dccf53feed800f5d40c7f..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/main_sc_rollup_node_014_PtKathma.ml +++ /dev/null @@ -1,259 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* Copyright (c) 2022 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 error += Bad_minimal_fees of string - -let () = - register_error_kind - `Permanent - ~id:"bad_minimal_fees_arg" - ~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) - -let sc_rollup_address_param = - Clic.param - ~name:"sc-rollup-address" - ~desc:"The smart-contract rollup address" - (Clic.parameter (fun _ s -> - match Protocol.Alpha_context.Sc_rollup.Address.of_b58check_opt s with - | None -> failwith "Invalid smart-contract rollup address" - | Some addr -> return addr)) - -let sc_rollup_node_operator_param = - let open Lwt_result_syntax in - Clic.param - ~name:"node-operator" - ~desc:"Public key hash of the the smart-contract rollup node operator" - (Clic.parameter (fun _ s -> - match Signature.Public_key_hash.of_b58check_opt s with - | None -> - failwith "Could not read public key hash for rollup node operator" - | Some pkh -> return pkh)) - -let rpc_addr_arg = - let default = Configuration.default_rpc_addr in - Clic.default_arg - ~long:"rpc-addr" - ~placeholder:"rpc-address|ip" - ~doc: - (Format.sprintf - "The address the smart-contract rollup node listens to. Default value \ - is %s" - default) - ~default - Client_proto_args.string_parameter - -let rpc_port_arg = - let default = Configuration.default_rpc_port |> string_of_int in - Clic.default_arg - ~long:"rpc-port" - ~placeholder:"rpc-port" - ~doc: - (Format.sprintf - "The port the smart-contract rollup node listens to. Default value is \ - %s" - default) - ~default - Client_proto_args.int_parameter - -let data_dir_arg = - let default = Configuration.default_data_dir in - Clic.default_arg - ~long:"data-dir" - ~placeholder:"data-dir" - ~doc: - (Format.sprintf - "The path to the smart-contract rollup node data directory. Default \ - value is %s" - default) - ~default - Client_proto_args.string_parameter - -let minimal_fees_arg = - let open Protocol.Alpha_context in - let default = - Configuration.default_fee_parameter.minimal_fees |> Tez.to_string - in - Clic.default_arg - ~long:"minimal-fees" - ~placeholder:"amount" - ~doc: - "Exclude operations with fees lower than this threshold (in tez) when \ - injecting." - ~default - (Clic.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 = - let default = - Configuration.default_fee_parameter.minimal_nanotez_per_gas_unit - |> Q.to_string - in - Clic.default_arg - ~long:"minimal-nanotez-per-gas-unit" - ~placeholder:"amount" - ~doc: - "Exclude operations with fees per gas lower than this threshold (in \ - nanotez) when injecting." - ~default - (Clic.parameter (fun _ s -> - try return (Q.of_string s) with _ -> fail (Bad_minimal_fees s))) - -let minimal_nanotez_per_byte_arg = - let default = - Configuration.default_fee_parameter.minimal_nanotez_per_byte |> Q.to_string - in - Clic.default_arg - ~long:"minimal-nanotez-per-byte" - ~placeholder:"amount" - ~default - ~doc: - "Exclude operations with fees per byte lower than this threshold (in \ - nanotez) when injecting." - (Clic.parameter (fun _ s -> - try return (Q.of_string s) with _ -> fail (Bad_minimal_fees s))) - -let force_low_fee_arg = - Clic.switch - ~long:"force-low-fee" - ~doc: - "Don't check that the fee is lower than the estimated default value when \ - injecting." - () - -let fee_cap_arg = - let open Protocol.Alpha_context in - let default = Configuration.default_fee_parameter.fee_cap |> Tez.to_string in - Clic.default_arg - ~long:"fee-cap" - ~placeholder:"amount" - ~default - ~doc:"Set the fee cap when injecting." - (Clic.parameter (fun _ s -> - match Tez.of_string s with - | Some t -> return t - | None -> failwith "Bad fee cap")) - -let burn_cap_arg = - let open Protocol.Alpha_context in - let default = Configuration.default_fee_parameter.burn_cap |> Tez.to_string in - Clic.default_arg - ~long:"burn-cap" - ~placeholder:"amount" - ~default - ~doc:"Set the burn cap when injecting." - (Clic.parameter (fun _ s -> - match Tez.of_string s with - | Some t -> return t - | None -> failwith "Bad burn cap")) - -let group = - { - Clic.name = "sc_rollup.node"; - title = "Commands related to the smart-contract rollup node."; - } - -let config_init_command = - let open Clic in - command - ~group - ~desc:"Configure the smart-contract rollup node." - (args9 - data_dir_arg - rpc_addr_arg - rpc_port_arg - 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 ["config"; "init"; "on"] - @@ sc_rollup_address_param - @@ prefixes ["with"; "operator"] - @@ sc_rollup_node_operator_param stop) - (fun ( data_dir, - rpc_addr, - rpc_port, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - sc_rollup_address - sc_rollup_node_operator - cctxt -> - let open Configuration in - let config = - { - data_dir; - sc_rollup_address; - sc_rollup_node_operator; - rpc_addr; - rpc_port; - fee_parameter = - { - minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - }; - } - in - save config >>=? fun () -> - cctxt#message - "Smart-contract rollup node configuration written in %s" - (filename config) - >>= fun _ -> return ()) - -let run_command = - let open Clic in - command - ~group - ~desc:"Run the rollup daemon." - (args1 data_dir_arg) - (prefixes ["run"] @@ stop) - (fun data_dir cctxt -> Daemon.run ~data_dir cctxt >>=? fun () -> return ()) - -let sc_rollup_commands () = - List.map - (Clic.map_command (new Protocol_client_context.wrap_full)) - [config_init_command; run_command] - -let select_commands _ _ = - return (sc_rollup_commands () @ Client_helpers_commands.commands ()) - -let () = Client_main_run.run (module Daemon_config) ~select_commands diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/node_context.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/node_context.ml deleted file mode 100644 index d769f4f3082ca99bed989fc761843bb8452a34b9..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/node_context.ml +++ /dev/null @@ -1,64 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 = { - cctxt : Protocol_client_context.full; - rollup_address : Sc_rollup.t; - operator : Signature.Public_key_hash.t; - initial_level : Raw_level.t; - block_finality_time : int; - kind : Sc_rollup.Kind.t; - fee_parameter : Injection.fee_parameter; -} - -let get_operator_keys node_ctxt = - let open Lwt_result_syntax in - let+ _, pk, sk = Client_keys.get_key node_ctxt.cctxt node_ctxt.operator in - (node_ctxt.operator, pk, sk) - -let init (cctxt : Protocol_client_context.full) rollup_address operator - fee_parameter = - let open Lwt_result_syntax in - let* initial_level = - Plugin.RPC.Sc_rollup.initial_level - cctxt - (cctxt#chain, cctxt#block) - rollup_address - in - let+ kind = - Plugin.RPC.Sc_rollup.kind cctxt (cctxt#chain, cctxt#block) rollup_address () - in - { - cctxt; - rollup_address; - operator; - initial_level; - kind; - block_finality_time = 2; - fee_parameter; - } diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/node_context.mli b/src/proto_014_PtKathma/bin_sc_rollup_node/node_context.mli deleted file mode 100644 index e51c11150b6c8c9fefe08e3f4f54c4f8c19a6b81..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/node_context.mli +++ /dev/null @@ -1,65 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 describes the execution context of the node. *) - -open Protocol -open Alpha_context - -type t = { - cctxt : Protocol_client_context.full; - (** Client context used by the rollup node. *) - rollup_address : Sc_rollup.t; - (** Smart contract rollup tracked by the rollup node. *) - operator : Signature.Public_key_hash.t; - (** Address of the rollup node operator. *) - initial_level : Raw_level.t; - (** Origination level of the smart contract rollup. *) - block_finality_time : int; - (** Deterministic block finality time for the layer 1 protocol. *) - kind : Sc_rollup.Kind.t; (** Kind of the smart contract rollup. *) - fee_parameter : Injection.fee_parameter; - (** Fee parameter to use when injecting operations in layer 1. *) -} - -(** [get_operator_keys cctxt] returns a triple [(pkh, pk, sk)] corresponding - to the address, public key, and secret key URI of the rollup node operator. -*) -val get_operator_keys : - t -> - (Signature.Public_key_hash.t * Signature.Public_key.t * Client_keys.sk_uri) - tzresult - Lwt.t - -(** [init cctxt sc_rollup operator_pkh] initialises the rollup representation. - The rollup origination level and kind are fetched via an RPC call to the - layer1 node that [cctxt] uses for RPC requests. -*) -val init : - Protocol_client_context.full -> - Sc_rollup.t -> - Signature.Public_key_hash.t -> - Injection.fee_parameter -> - t tzresult Lwt.t diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/pvm.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/pvm.ml deleted file mode 100644 index 0c44a30b61a9ec85315402d7d166f3f09b4f0b49..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/pvm.ml +++ /dev/null @@ -1,48 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 - -(** Desired module type of a PVM from the L2 node's perspective *) -module type S = sig - include - Sc_rollup.PVM.S - with type context = Store.t - and type state = Store.tree - and type hash = Sc_rollup.State_hash.t - - (** [get_tick state] gets the total tick counter for the given PVM state. *) - val get_tick : state -> Sc_rollup.Tick.t Lwt.t - - (** PVM status *) - type status - - (** [get_status state] gives you the current execution status for the PVM. *) - val get_status : state -> status Lwt.t - - (** [string_of_status status] returns a string representation of [status]. *) - val string_of_status : status -> string -end diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/store.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/store.ml deleted file mode 100644 index 16e30f0ac0daeafed8069ce5733d03bc2b821126..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/store.ml +++ /dev/null @@ -1,379 +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 Maker = Irmin_pack_unix.Maker (Tezos_context_encoding.Context.Conf) - -module IStore = struct - include Maker.Make (Tezos_context_encoding.Context.Schema) - module Schema = Tezos_context_encoding.Context.Schema -end - -type t = IStore.t - -type tree = IStore.tree - -type path = string list - -let load configuration = - let open Lwt_syntax in - let open Configuration in - let* repo = IStore.Repo.v (Irmin_pack.config configuration.data_dir) in - IStore.main repo - -let flush store = IStore.flush (IStore.repo store) - -let close store = IStore.Repo.close (IStore.repo store) - -let info message = - let date = Unix.gettimeofday () |> int_of_float |> Int64.of_int in - Irmin.Info.Default.v ~author:"Tezos smart-contract rollup node" ~message date - -module type Mutable_value = sig - type value - - val path_key : path - - val decode_value : bytes -> value Lwt.t - - val set : t -> value -> unit Lwt.t - - val get : t -> value Lwt.t - - val find : t -> value option Lwt.t -end - -module Make_append_only_map (P : sig - val path : path - - val keep_last_n_entries_in_memory : int - - type key - - val string_of_key : key -> string - - type value - - val value_encoding : value Data_encoding.t -end) = -struct - (* Ignored for now. *) - let _ = P.keep_last_n_entries_in_memory - - let path_key = P.path - - let make_key key = path_key @ [P.string_of_key key] - - let mem store key = IStore.mem store (make_key key) - - let decode_value encoded_value = - Lwt.return - @@ Data_encoding.Binary.of_bytes_exn P.value_encoding encoded_value - - let get store key = IStore.get store (make_key key) >>= decode_value - - let find store key = - let open Lwt_syntax in - let* exists = mem store key in - if exists then - let+ value = get store key in - Some value - else return_none - - let find_with_default store key ~on_default = - let open Lwt_syntax in - let* exists = mem store key in - if exists then get store key else return (on_default ()) - - let add store key value = - let open Lwt_syntax in - let* existing_value = find store key in - let full_path = String.concat "/" (P.path @ [P.string_of_key key]) in - let encode v = Data_encoding.Binary.to_bytes_exn P.value_encoding v in - let encoded_value = encode value in - match existing_value with - | None -> - let info () = info full_path in - IStore.set_exn ~info store (make_key key) encoded_value - | Some existing_value -> - (* To be robust to interruption in the middle of processes, - we accept to redo some work when we restart the node. - Hence, it is fine to insert twice the same value for a - given value. *) - if not (Bytes.equal (encode existing_value) encoded_value) then - Stdlib.failwith - (Printf.sprintf - "Key %s already exists with a different value" - full_path) - else return_unit -end - -module Make_mutable_value (P : sig - val path : path - - type value - - val value_encoding : value Data_encoding.t -end) = -struct - type value = P.value - - let path_key = P.path - - let decode_value encoded_value = - Lwt.return - @@ Data_encoding.Binary.of_bytes_exn P.value_encoding encoded_value - - let set store value = - let encoded_value = - Data_encoding.Binary.to_bytes_exn P.value_encoding value - in - let info () = info (String.concat "/" P.path) in - IStore.set_exn ~info store path_key encoded_value - - let get store = IStore.get store path_key >>= decode_value - - let find store = - let open Lwt_syntax in - let* value = IStore.find store path_key in - Option.map_s decode_value value -end - -module IStoreTree = struct - include - Tezos_context_helpers.Context.Make_tree - (Tezos_context_encoding.Context.Conf) - (IStore) - - type t = IStore.t - - type tree = IStore.tree - - type key = path - - type value = bytes -end - -module IStoreProof = - Tezos_context_helpers.Context.Make_proof - (IStore) - (Tezos_context_encoding.Context.Conf) - -module Inbox = struct - include Sc_rollup.Inbox - include Sc_rollup.Inbox.MakeHashingScheme (IStoreTree) -end - -(** State of the PVM that this rollup node deals with *) -module PVMState = struct - let[@inline] key block_hash = ["pvm_state"; Block_hash.to_b58check block_hash] - - let find store block_hash = IStore.find_tree store (key block_hash) - - let exists store block_hash = IStore.mem store (key block_hash) - - let set store block_hash state = - IStore.set_tree_exn - ~info:(fun () -> info "Update PVM state") - store - (key block_hash) - state - - let init_s store block_hash make_state = - let open Lwt_syntax in - let* exists = exists store block_hash in - if exists then return_unit - else - let* state = make_state () in - set store block_hash state -end - -(** Aggregated collection of messages from the L1 inbox *) -module MessageTrees = struct - let[@inline] key block_hash = - ["message_tree"; Block_hash.to_b58check block_hash] - - (** [get store block_hash] retrieves the message tree for [block_hash]. If it is not present, an empty - tree is returned. *) - let get store block_hash = - let open Lwt_syntax in - let+ tree = IStore.find_tree store (key block_hash) in - Option.value ~default:(IStoreTree.empty ()) tree - - (** [set store block_hash message_tree] set the message tree for [block_hash]. *) - let set store block_hash message_tree = - IStore.set_tree_exn - ~info:(fun () -> info "Update messages tree") - store - (key block_hash) - message_tree -end - -type state_info = {num_messages : Z.t; num_ticks : Z.t} - -(** Extraneous state information for the PVM *) -module StateInfo = Make_append_only_map (struct - let path = ["state_info"] - - let keep_last_n_entries_in_memory = 6000 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = state_info - - let value_encoding = - let open Data_encoding in - conv - (fun {num_messages; num_ticks} -> (num_messages, num_ticks)) - (fun (num_messages, num_ticks) -> {num_messages; num_ticks}) - (obj2 - (req "num_messages" Data_encoding.z) - (req "num_ticks" Data_encoding.z)) -end) - -(** Unaggregated messages per block *) -module Messages = Make_append_only_map (struct - let path = ["messages"] - - let keep_last_n_entries_in_memory = 10 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = string list - - let value_encoding = Data_encoding.(list string) -end) - -(** Inbox state for each block *) -module Inboxes = Make_append_only_map (struct - let path = ["inboxes"] - - let keep_last_n_entries_in_memory = 10 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = Sc_rollup.Inbox.t - - let value_encoding = Sc_rollup.Inbox.encoding -end) - -(** Message history for the inbox at a given block *) -module Histories = Make_append_only_map (struct - let path = ["histories"] - - let keep_last_n_entries_in_memory = 10 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = Inbox.history - - let value_encoding = Inbox.history_encoding -end) - -module Commitments = Make_append_only_map (struct - let path = ["commitments"; "computed"] - - let keep_last_n_entries_in_memory = 10 - - type key = Raw_level.t - - let string_of_key l = Int32.to_string @@ Raw_level.to_int32 l - - type value = Sc_rollup.Commitment.t * Sc_rollup.Commitment.Hash.t - - let value_encoding = - Data_encoding.( - obj2 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding)) -end) - -module Last_stored_commitment_level = Make_mutable_value (struct - let path = ["commitments"; "last_stored_level"] - - type value = Raw_level.t - - let value_encoding = Raw_level.encoding -end) - -module Last_published_commitment_level = Make_mutable_value (struct - let path = ["commitments"; "last_published_level"] - - type value = Raw_level.t - - let value_encoding = Raw_level.encoding -end) - -module Last_cemented_commitment_level = Make_mutable_value (struct - let path = ["commitments"; "last_cemented_commitment"; "level"] - - type value = Raw_level.t - - let value_encoding = Raw_level.encoding -end) - -module Last_cemented_commitment_hash = Make_mutable_value (struct - let path = ["commitments"; "last_cemented_commitment"; "hash"] - - type value = Sc_rollup.Commitment.Hash.t - - let value_encoding = Sc_rollup.Commitment.Hash.encoding -end) - -module Commitments_published_at_level = Make_append_only_map (struct - let path = ["commitments"; "published_at_level"] - - let keep_last_n_entries_in_memory = 10 - - type key = Sc_rollup.Commitment.Hash.t - - let string_of_key = Sc_rollup.Commitment.Hash.to_b58check - - type value = Raw_level.t - - let value_encoding = Raw_level.encoding -end) - -module Dal_slot_subscriptions = Make_append_only_map (struct - let path = ["dal"; "slot_subscriptions"] - - let keep_last_n_entries_in_memory = 10 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = Dal.Slot_index.t list - - let value_encoding = Data_encoding.list Dal.Slot_index.encoding -end) diff --git a/src/proto_014_PtKathma/bin_sc_rollup_node/wasm_2_0_0_pvm.ml b/src/proto_014_PtKathma/bin_sc_rollup_node/wasm_2_0_0_pvm.ml deleted file mode 100644 index 38fc7322794b109729cf3a88cf7633a865ae4231..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/bin_sc_rollup_node/wasm_2_0_0_pvm.ml +++ /dev/null @@ -1,91 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 manifests the proof format used by the Wasm PVM as defined by - the Layer 1 implementation for it. - - It is imperative that this is aligned with the protocol's implementation. -*) -module Wasm_2_0_0_proof_format = struct - open Store - - type proof = IStoreProof.Proof.tree IStoreProof.Proof.t - - let produce_proof context tree step = - let open Lwt_syntax in - match IStoreTree.kinded_key tree with - | Some k -> - let* p = IStoreProof.produce_tree_proof (IStore.repo context) k step in - return (Some p) - | None -> return None - - let verify_proof proof step = - (* The rollup node is not supposed to verify proof. We keep - this part in case this changes in the future. *) - let open Lwt_syntax in - let* result = IStoreProof.verify_tree_proof proof step in - match result with - | Ok v -> return (Some v) - | Error _ -> - (* We skip the error analysis here since proof verification is not a - job for the rollup node. *) - return None - - let kinded_hash_to_state_hash : - IStoreProof.Proof.kinded_hash -> Sc_rollup.State_hash.t = function - | `Value hash | `Node hash -> - Sc_rollup.State_hash.hash_bytes [Context_hash.to_bytes hash] - - let proof_before proof = - kinded_hash_to_state_hash proof.IStoreProof.Proof.before - - let proof_after proof = - kinded_hash_to_state_hash proof.IStoreProof.Proof.after - - let proof_encoding = - Tezos_context_merkle_proof_encoding.Merkle_proof_encoding.V2.Tree32 - .tree_proof_encoding -end - -module Impl : Pvm.S = struct - include Sc_rollup.Wasm_2_0_0PVM.Make (struct - open Store - module Tree = IStoreTree - - type tree = IStoreTree.tree - - include Wasm_2_0_0_proof_format - end) - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3093 - Print a more informative status. - *) - let string_of_status _status = "" -end - -include Impl diff --git a/src/proto_014_PtKathma/lib_protocol/test/pbt/dune b/src/proto_014_PtKathma/lib_protocol/test/pbt/dune index b91a78686dc0c873791db5ad4d60fa6991d53992..1982a60e1a87ac51fee21a08bd9a28759d3d72c1 100644 --- a/src/proto_014_PtKathma/lib_protocol/test/pbt/dune +++ b/src/proto_014_PtKathma/lib_protocol/test/pbt/dune @@ -13,7 +13,6 @@ test_tx_rollup_l2_encoding test_bitset test_sc_rollup_tick_repr - test_refutation_game test_carbonated_map) (libraries tezos-base @@ -89,11 +88,6 @@ (package tezos-protocol-014-PtKathma-tests) (action (run %{dep:./test_sc_rollup_tick_repr.exe}))) -(rule - (alias runtest) - (package tezos-protocol-014-PtKathma-tests) - (action (run %{dep:./test_refutation_game.exe}))) - (rule (alias runtest) (package tezos-protocol-014-PtKathma-tests) @@ -119,6 +113,4 @@ (rule (alias runtest2) (action (run %{exe:test_sc_rollup_tick_repr.exe}))) -(rule (alias runtest3) (action (run %{exe:test_refutation_game.exe}))) - (rule (alias runtest3) (action (run %{exe:test_carbonated_map.exe}))) diff --git a/src/proto_014_PtKathma/lib_protocol/test/pbt/test_refutation_game.ml b/src/proto_014_PtKathma/lib_protocol/test/pbt/test_refutation_game.ml deleted file mode 100644 index 229943e855e5f859ec24217f1105031870c1a83a..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/lib_protocol/test/pbt/test_refutation_game.ml +++ /dev/null @@ -1,988 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* Copyright (c) 2022 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: PBT for the SCORU refutation game - Invocation: dune exec \ - src/proto_alpha/lib_protocol/test/pbt/test_refutation_game.exe - Subject: SCORU refutation game -*) -open Protocol - -open Alpha_context -open Sc_rollup -open Lwt_syntax -open Lib_test.Qcheck2_helpers - -(** - - Helpers - -*) - -let zero_level = - Raw_level.of_int32 0l |> function Ok x -> x | _ -> assert false - -let hash_state state number = - Digest.bytes @@ Bytes.of_string @@ state ^ string_of_int number - -type dummy_proof = { - start : State_hash.t; - stop : State_hash.t option; - valid : bool; -} - -module Tick_map = Map.Make (Sc_rollup_tick_repr) - -let dummy_proof_encoding : dummy_proof Data_encoding.t = - let open Data_encoding in - conv - (fun {start; stop; valid} -> (start, stop, valid)) - (fun (start, stop, valid) -> {start; stop; valid}) - (obj3 - (req "start" State_hash.encoding) - (req "stop" (option State_hash.encoding)) - (req "valid" bool)) - -let proof_start_state proof = proof.start - -let proof_stop_state proof = proof.stop - -let number_of_messages_exn n = - match Number_of_messages.of_int32 n with - | Some x -> x - | None -> Stdlib.failwith "Bad Number_of_messages" - -let number_of_ticks_exn n = - match Number_of_ticks.of_int32 n with - | Some x -> x - | None -> Stdlib.failwith "Bad Number_of_ticks" - -let get_comm pred inbox_level messages ticks state = - Commitment. - { - predecessor = pred; - inbox_level = Raw_level.of_int32_exn inbox_level; - number_of_messages = number_of_messages_exn messages; - number_of_ticks = number_of_ticks_exn ticks; - compressed_state = state; - } - -let random_hash () = State_hash.of_bytes_exn @@ Bytes.create 32 - -let tick_of_int_exn n = - match Tick.of_int n with None -> assert false | Some t -> t - -let tick_to_int_exn t = - match Tick.to_int t with None -> assert false | Some n -> n - -let random_dissection start_at start_hash stop_at stop_hash : - (State_hash.t option * Tick.t) list option Lwt.t = - let start_int = tick_to_int_exn start_at in - let stop_int = tick_to_int_exn stop_at in - let dist = stop_int - start_int in - let branch = min (dist + 1) 32 in - let size = (dist + 1) / (branch - 1) in - - if dist = 1 then return None - else - return - @@ Result.to_option - (List.init branch ~when_negative_length:"error" (fun i -> - if i = 0 then (Some start_hash, start_at) - else if i = branch - 1 then (stop_hash, stop_at) - else - (Some (random_hash ()), tick_of_int_exn (start_int + (i * size))))) - -(** - `genlist` is a `correct list` generator. It generates a list of strings that - are either integers or `+` to be consumed by the arithmetic PVM. - If a `+` is found then the previous two element of the stack are poped - then added and the result is pushed to the stack. - In particular, lists like `[1 +]` are incorrect. - - To preserve the correctness invariant, genlist is a recursive generator that - produce a pair `(stack_size, state_list)` where state_list is a correct list - of integers and `+` and consuming it will produce a `stack` of length - `stack_size`. - For example a result can be `(3, [1; 2; +; 3; +; 2; 2; +; 1;]). - Consuming the list will produce the stack`[6; 4; 2]` which has length 3. - The generator has two branches. - 1. with frequency 1 adds integers to state_list and increases the - corresponding stack_size. - 2. With frequency 2, at each step, it looks at the inductive result - `(self (n - 1))=(stack_size, state_list)`. - If the stack_size is smaller than 2 then it adds an integer to the state_list - and increases the stack_size - Otherwise it adds a plus to the state_list and decreases the stack_size. - Remark: The algorithm is linear in the size of the generated list and - generates all kinds of inputs not only those that produce a stack of size 1. -*) -let gen_list = - QCheck2.Gen.( - map (fun (_, l) -> List.rev l) - @@ sized_size small_nat - @@ fix (fun self n -> - match n with - | 0 -> map (fun x -> (1, [string_of_int x])) small_nat - | n -> - frequency - [ - ( 2, - map2 - (fun x (stack_size, state_list) -> - if stack_size >= 2 then - (stack_size - 1, "+" :: state_list) - else (stack_size + 1, string_of_int x :: state_list)) - small_nat - (self (n - 1)) ); - ( 1, - map2 - (fun x (i, y) -> (i + 1, string_of_int x :: y)) - small_nat - (self (n - 1)) ); - ])) - -(** This uses the above generator to produce a correct program with at - least 3 elements. *) -let rec correct_string () = - let x = QCheck2.Gen.(generate1 gen_list) in - if List.length x < 3 then correct_string () else x - -module type TestPVM = sig - include PVM.S with type hash = State_hash.t - - module Utils : sig - (** This a post-boot state. It is used as default in many functions. *) - val default_state : state - - (** [random_state n state] generates a random state. The integer n is - used as a seed in the generation. *) - val random_state : int -> state -> state - - (** [make_proof start_state stop_state] produces a proof that the eval of - [start_state] is the [stop_state]. - It will be used by the `verify_proof`. In the arithPVM we use - `produce_tree_proof` which only requires a starting state (tree) - and the transition function. *) - val make_proof : state -> hash option -> proof Lwt.t - - (** Like [make_proof] but produces an invalid proof starting from - any hash. *) - val make_invalid_proof : hash -> hash option -> proof Lwt.t - end -end - -(** - - [MakeCountingPVM (P)] is a PVM whose state is an integer and that - can count up to a certain [P.target]. - - This PVM has no input states. - -*) -module MakeCountingPVM (P : sig - val target : int -end) : TestPVM with type state = int = struct - let name = "countingPVM" - - let parse_boot_sector x = Some x - - let pp_boot_sector fmt x = Format.fprintf fmt "%s" x - - type state = int - - type hash = State_hash.t - - type context = unit - - type proof = dummy_proof - - let proof_start_state = proof_start_state - - let proof_stop_state = proof_stop_state - - let proof_input_given _ = None - - let proof_input_requested _ = No_input_required - - let state_hash (x : state) = return (State_hash.hash_string [Int.to_string x]) - - let is_input_state x = - if x >= P.target then return Initial else return No_input_required - - let initial_state _ _ = return P.target - - let set_input _ s = return s - - module Utils = struct - let default_state = P.target - - let random_state _ _ = Random.bits () - - let make_proof s1 s2 = - let* s1 = state_hash s1 in - return {start = s1; stop = s2; valid = true} - - let make_invalid_proof s1 s2 = return {start = s1; stop = s2; valid = false} - end - - let proof_encoding = dummy_proof_encoding - - let eval state = if state >= P.target then return state else return (state + 1) - - let verify_proof proof = return proof.valid - - let produce_proof _ _ _ = Stdlib.failwith "Dummy PVM can't produce proof" - - type output_proof = unit - - let output_proof_encoding = Data_encoding.unit - - let state_of_output_proof _ = - Stdlib.failwith "Dummy PVM can't handle output proof" - - let output_of_output_proof _ = - Stdlib.failwith "Dummy PVM can't handle output proof" - - let verify_output_proof _ = - Stdlib.failwith "Dummy PVM can't handle output proof" - - let produce_output_proof _ _ _ = - Stdlib.failwith "Dummy PVM can't handle output proof" -end - -(** This is a random PVM. Its state is a pair of a string and a - list of integers. An evaluation step consumes the next integer - of the list and concatenates its representation to the string. *) -module MakeRandomPVM (P : sig - val initial_prog : int list -end) : TestPVM with type state = string * int list = struct - let name = "randomPVM" - - let parse_boot_sector x = Some x - - let pp_boot_sector fmt x = Format.fprintf fmt "%s" x - - type state = string * int list - - type context = unit - - type proof = dummy_proof - - type hash = State_hash.t - - let to_string (a, b) = - Format.sprintf "(%s, [%s])" a (String.concat ";" @@ List.map Int.to_string b) - - let proof_start_state = proof_start_state - - let proof_stop_state = proof_stop_state - - let proof_input_given _ = None - - let proof_input_requested _ = No_input_required - - let state_hash (x : state) = return @@ State_hash.hash_string [to_string x] - - let initial_state _ _ = return ("hello", P.initial_prog) - - let is_input_state (_, c) = - match c with [] -> return Initial | _ -> return No_input_required - - let set_input _ state = return state - - module Utils = struct - let default_state = ("hello", P.initial_prog) - - let random_state length ((_, program) : state) = - let remaining_program = TzList.drop_n length program in - let (stop_state : state) = - (hash_state "" (Random.bits ()), remaining_program) - in - stop_state - - let make_proof s1 s2 = - let* s1 = state_hash s1 in - return {start = s1; stop = s2; valid = true} - - let make_invalid_proof s1 s2 = return {start = s1; stop = s2; valid = false} - end - - let proof_encoding = dummy_proof_encoding - - let eval (hash, continuation) = - match continuation with - | [] -> return (hash, continuation) - | h :: tl -> return (hash_state hash h, tl) - - let verify_proof proof = return proof.valid - - let produce_proof _ _ _ = Stdlib.failwith "Dummy PVM can't produce proof" - - type output_proof = unit - - let output_proof_encoding = Data_encoding.unit - - let state_of_output_proof _ = - Stdlib.failwith "Dummy PVM can't handle output proof" - - let output_of_output_proof _ = - Stdlib.failwith "Dummy PVM can't handle output proof" - - let verify_output_proof _ = - Stdlib.failwith "Dummy PVM can't handle output proof" - - let produce_output_proof _ _ _ = - Stdlib.failwith "Dummy PVM can't handle output proof" -end - -module ContextPVM = ArithPVM.Make (struct - open Tezos_context_memory.Context - - module Tree = struct - include Tezos_context_memory.Context.Tree - - type tree = Tezos_context_memory.Context.tree - - type t = Tezos_context_memory.Context.t - - type key = string list - - type value = bytes - end - - type tree = Tree.tree - - type proof = Proof.tree Proof.t - - let verify_proof proof f = - Lwt.map Result.to_option (verify_tree_proof proof f) - - let produce_proof context state f = - let* proof = - produce_tree_proof (index context) (`Value (Tree.hash state)) f - in - return (Some proof) - - let kinded_hash_to_state_hash = function - | `Value hash | `Node hash -> - State_hash.hash_bytes [Context_hash.to_bytes hash] - - let proof_before proof = kinded_hash_to_state_hash proof.Proof.before - - let proof_after proof = kinded_hash_to_state_hash proof.Proof.after - - let proof_encoding = - let open Data_encoding in - conv (fun _ -> ()) (fun _ -> assert false) unit -end) - -module TestArith (P : sig - val inputs : string - - val evals : int -end) : TestPVM = struct - include ContextPVM - - let init_context = Tezos_context_memory.make_empty_context () - - module Utils = struct - let default_state = - let promise = - let* boot = initial_state init_context "" >>= eval in - let input = - { - inbox_level = Raw_level.root; - message_counter = Z.zero; - payload = P.inputs; - } - in - let prelim = set_input input boot in - List.fold_left (fun acc _ -> acc >>= fun acc -> eval acc) prelim - @@ List.repeat P.evals () - in - Lwt_main.run promise - - let random_state i state = - let program = correct_string () in - let input = - { - inbox_level = Raw_level.root; - message_counter = Z.zero; - payload = String.concat " " program; - } - in - let prelim = set_input input state in - Lwt_main.run - @@ List.fold_left (fun acc _ -> acc >>= fun acc -> eval acc) prelim - @@ List.repeat (min i (List.length program - 2) + 1) () - - let make_proof s1 _s2 = - let* proof_opt = produce_proof init_context None s1 in - match proof_opt with Ok proof -> return proof | Error _ -> assert false - - let make_invalid_proof _ _ = - let* state = initial_state init_context "foooobaaar" in - let* proof_opt = produce_proof init_context None state in - match proof_opt with Ok proof -> return proof | Error _ -> assert false - end -end - -(** - This module introduces some testing strategies for a game created - from a PVM. -*) -module Strategies (PVM : TestPVM with type hash = State_hash.t) = struct - (** [exec_all state tick] runs eval until the state machine reaches a - state where it requires an input. It returns the new state and the - final tick. - *) - let exec_all state tick = - let rec loop state tick = - let* isinp = PVM.is_input_state state in - match isinp with - | No_input_required -> - let* s = PVM.eval state in - let* hash1 = PVM.state_hash state in - let* hash2 = PVM.state_hash s in - - if State_hash.equal hash1 hash2 then assert false - else loop s (Tick.next tick) - | _ -> return (state, tick) - in - loop state tick - - (** [state_at to_tick from_state from_tick] returns the state at tick - [to_tick], or [None] if that's past the point at which the machine - has stopped. *) - let state_at to_tick from_state from_tick = - let rec loop state tick = - let* isinp = PVM.is_input_state state in - if Tick.equal to_tick tick then return (Some state, tick) - else - match isinp with - | No_input_required -> - let* s = PVM.eval state in - let* hash1 = PVM.state_hash state in - let* hash2 = PVM.state_hash s in - - if State_hash.equal hash1 hash2 then assert false - else loop s (Tick.next tick) - | _ -> return (None, to_tick) - in - loop from_state from_tick - - (** [dissection_of_section start_tick start_state stop_tick] creates - a dissection with at most [32] pieces that are (roughly) equal - spaced and whose states are computed by running the eval function - until the correct tick. Note that the last piece can be as much - as 31 ticks longer than the others. *) - let dissection_of_section start_tick start_state stop_tick = - let start_int = tick_to_int_exn start_tick in - let stop_int = tick_to_int_exn stop_tick in - let dist = stop_int - start_int in - if dist = 1 then return None - else - let branch = min (dist + 1) 32 in - let size = (dist + 1) / (branch - 1) in - let tick_list = - Result.to_option - @@ List.init branch ~when_negative_length:"error" (fun i -> - if i = branch - 1 then stop_tick - else tick_of_int_exn (start_int + (i * size))) - in - let a = - Option.map - (fun a -> - List.map - (fun tick -> - let hash = - Lwt_main.run - @@ let* state, _ = state_at tick start_state start_tick in - match state with - | None -> return None - | Some s -> - let* h = PVM.state_hash s in - return (Some h) - in - (hash, tick)) - a) - tick_list - in - return a - - type client = { - initial : (Tick.t * PVM.hash) option Lwt.t; - next_move : Game.t -> Game.refutation option Lwt.t; - } - - type outcome_for_tests = Defender_wins | Refuter_wins - - let equal_outcome a b = - match (a, b) with - | Defender_wins, Defender_wins -> true - | Refuter_wins, Refuter_wins -> true - | _ -> false - - let loser_to_outcome_for_tests loser alice_is_refuter = - match loser with - | Game.Bob -> if alice_is_refuter then Refuter_wins else Defender_wins - | Game.Alice -> if alice_is_refuter then Defender_wins else Refuter_wins - - let run ~inbox ~refuter_client ~defender_client = - let refuter, _, _ = Signature.generate_key () in - let defender, _, _ = Signature.generate_key () in - let alice_is_refuter = Staker.(refuter < defender) in - let* start_hash = PVM.state_hash PVM.Utils.default_state in - let* initial_data = defender_client.initial in - let tick, initial_hash = - match initial_data with None -> assert false | Some s -> s - in - let int_tick = tick_to_int_exn tick in - let number_of_ticks = Int32.of_int int_tick in - let parent = get_comm Commitment.Hash.zero 0l 3l 1l start_hash in - let child = - get_comm Commitment.Hash.zero 0l 3l number_of_ticks initial_hash - in - let initial_game = - Game.initial inbox ~pvm_name:PVM.name ~parent ~child ~refuter ~defender - in - let* outcome = - let rec loop game refuter_move = - let* move = - if refuter_move then refuter_client.next_move game - else defender_client.next_move game - in - match move with - | None -> return (if refuter_move then Defender_wins else Refuter_wins) - | Some move -> ( - let* game_result = Game.play game move in - match game_result with - | Either.Left outcome -> - return - (loser_to_outcome_for_tests outcome.loser alice_is_refuter) - | Either.Right game -> loop game (not refuter_move)) - in - loop initial_game true - in - return outcome - - let random_tick ?(from = 0) () = - Option.value ~default:Tick.initial (Tick.of_int (from + Random.int 31)) - - (** - checks that the stop state of a section conflicts with the one computed by the - evaluation. - *) - let conflicting_section tick state = - let* new_state, _ = state_at tick PVM.Utils.default_state Tick.initial in - let* new_hash = - match new_state with - | None -> return None - | Some state -> - let* state = PVM.state_hash state in - return (Some state) - in - - return @@ not (Option.equal ( = ) state new_hash) - - (** This function assembles a random decision from a given dissection. - It first picks a random section from the dissection and modifies randomly - its states. - If the length of this section is one tick the returns a conclusion with - the given modified states. - If the length is longer it creates a random decision and outputs a Refine - decision with this dissection.*) - let random_decision d = - let number_of_somes = - List.length - (List.filter (function Some _, _ -> true | None, _ -> false) d) - in - let x = Random.int (number_of_somes - 1) in - let start_hash, start = - match List.nth d x with Some (Some s, t) -> (s, t) | _ -> assert false - in - let _, stop = - match List.nth d (x + 1) with - | Some (s, t) -> (s, t) - | None -> assert false - in - let stop_hash = Some (random_hash ()) in - let* random_dissection = - random_dissection start start_hash stop stop_hash - in - - match random_dissection with - | None -> - let* pvm_proof = - PVM.Utils.make_invalid_proof start_hash (Some (random_hash ())) - in - let wrapped = - let module P = struct - include PVM - - let proof = pvm_proof - end in - Unencodable (module P) - in - let proof = Proof.{pvm_step = wrapped; inbox = None} in - return (Some Game.{choice = start; step = Proof proof}) - | Some dissection -> - return (Some Game.{choice = start; step = Dissection dissection}) - - (** There are two kinds of strategies, random and machine-directed. *) - type strategy = Random | MachineDirected - - (** - [find_conflict dissection] finds the section (if it exists) in a dissection that - conflicts with the actual computation. *) - let find_conflict dissection = - let rec aux states = - match states with - | (start_state, start_tick) :: (next_state, next_tick) :: rest -> - let* c0 = conflicting_section start_tick start_state in - let* c = conflicting_section next_tick next_state in - if c0 then assert false - else if c then - if next_state = None then return None - else - return (Some ((start_state, start_tick), (next_state, next_tick))) - else aux ((next_state, next_tick) :: rest) - | _ -> return None - in - aux dissection - - (** [next_move branching dissection] finds the next move based on a - dissection. - It finds the first section of dissection that conflicts with the evaluation. - If the section has length one tick it returns a move with a Conclude - conflict_resolution_step. - If the section is longer it creates a new dissection with branching - many pieces and returns - a move with a Refine type conflict_resolution_step. - *) - let next_move dissection = - let* conflict = find_conflict dissection in - - match conflict with - | Some ((_, start_tick), (_, next_tick)) -> - let* start_state, _ = - state_at start_tick PVM.Utils.default_state Tick.initial - in - let* next_dissection = - match start_state with - | None -> return None - | Some s -> dissection_of_section start_tick s next_tick - in - let* stop_state, _ = - match start_state with - | None -> return (None, next_tick) - | Some s -> state_at next_tick s start_tick - in - let* refutation = - match next_dissection with - | None -> - let* stop_hash = - match stop_state with - | None -> return None - | Some state -> - let* s = PVM.state_hash state in - return (Some s) - in - let* pvm_proof = - match start_state with - | Some s -> PVM.Utils.make_proof s stop_hash - | None -> assert false - in - let wrapped = - let module P = struct - include PVM - - let proof = pvm_proof - end in - Unencodable (module P) - in - let proof = Proof.{pvm_step = wrapped; inbox = None} in - return Game.{choice = start_tick; step = Proof proof} - | Some next_dissection -> - return - Game.{choice = start_tick; step = Dissection next_dissection} - in - - return (Some refutation) - | None -> return None - - (** This is an automatic client. It generates a "perfect" client. *) - let machine_directed = - let start_state = PVM.Utils.default_state in - let initial = - let* stop_state, stop_at = exec_all start_state Tick.initial in - let* stop_hash = PVM.state_hash stop_state in - return (Some (stop_at, stop_hash)) - in - - let next_move (game : Game.t) = - let dissection = game.dissection in - let* mv = next_move dissection in - match mv with Some move -> return (Some move) | None -> return None - in - {initial; next_move} - - (** This builds a client from a strategy. If the strategy is - MachineDirected it uses the above constructions. If the strategy - is random then it uses a random section for the initial - commitments and the random decision for the next move. *) - let player_from_strategy = function - | Random -> - let initial = - let random_state = PVM.Utils.default_state in - let* stop_hash = PVM.state_hash random_state in - let random_tick = random_tick ~from:1 () in - return (Some (random_tick, stop_hash)) - in - {initial; next_move = (fun game -> random_decision game.dissection)} - | MachineDirected -> machine_directed - - (** [test_strategies defender_strategy refuter_strategy expectation inbox] - runs a game based oin the two given strategies and checks that the - resulting outcome fits the expectations. *) - let test_strategies defender_strategy refuter_strategy expectation inbox = - let defender_client = player_from_strategy defender_strategy in - let refuter_client = player_from_strategy refuter_strategy in - let* outcome = run ~inbox ~defender_client ~refuter_client in - return (expectation outcome) - - (** the possible expectation functions *) - let defender_wins = equal_outcome Defender_wins - - let refuter_wins = equal_outcome Refuter_wins - - let all_win _ = true -end - -(** The following are the possible combinations of strategies. *) -let perfect_perfect (module P : TestPVM) inbox = - let module R = Strategies (P) in - R.test_strategies MachineDirected MachineDirected R.defender_wins inbox - -let random_random (module P : TestPVM) inbox = - let module S = Strategies (P) in - S.test_strategies Random Random S.all_win inbox - -let random_perfect (module P : TestPVM) inbox = - let module S = Strategies (P) in - S.test_strategies Random MachineDirected S.refuter_wins inbox - -let perfect_random (module P : TestPVM) inbox = - let module S = Strategies (P) in - S.test_strategies MachineDirected Random S.defender_wins inbox - -(** This assembles a test from a RandomPVM and a function that chooses the - type of strategies. *) -let testing_randomPVM (f : (module TestPVM) -> Inbox.t -> bool Lwt.t) name = - let open QCheck2 in - Test.make - ~name - Gen.(list_size small_int (int_range 0 100)) - (fun initial_prog -> - assume (initial_prog <> []) ; - let rollup = Address.hash_string [""] in - let level = zero_level in - let inbox = Inbox.empty rollup level in - Lwt_main.run - @@ f - (module MakeRandomPVM (struct - let initial_prog = initial_prog - end)) - inbox) - -(** This assembles a test from a CountingPVM and a function that - chooses the type of strategies *) -let testing_countPVM (f : (module TestPVM) -> Inbox.t -> bool Lwt.t) name = - let open QCheck2 in - Test.make ~name Gen.small_int (fun target -> - assume (target > 200) ; - let rollup = Address.hash_string [""] in - let level = zero_level in - let inbox = Inbox.empty rollup level in - Lwt_main.run - @@ f - (module MakeCountingPVM (struct - let target = target - end)) - inbox) - -let testing_arith (f : (module TestPVM) -> Inbox.t -> bool Lwt.t) name = - let open QCheck2 in - Test.make - ~name - Gen.(pair gen_list small_int) - (fun (inputs, evals) -> - assume (evals > 1 && evals < List.length inputs - 1) ; - let rollup = Address.hash_string [""] in - let level = zero_level in - let inbox = Inbox.empty rollup level in - Lwt_main.run - @@ f - (module TestArith (struct - let inputs = String.concat " " inputs - - let evals = evals - end)) - inbox) - -let test_random_dissection (module P : TestPVM) start_at length = - let open P in - let module S = Strategies (P) in - let section_start_state = Utils.default_state in - let rec aux hash = - let new_hash = random_hash () in - if hash = new_hash then aux hash else new_hash - in - let section_stop_at = - match Tick.of_int (start_at + length) with - | None -> assert false - | Some x -> x - in - let section_start_at = - match Tick.of_int start_at with None -> assert false | Some x -> x - in - let* option_dissection = - S.dissection_of_section section_start_at section_start_state section_stop_at - in - let dissection = - match option_dissection with - | None -> raise (Invalid_argument "no dissection") - | Some x -> x - in - let* start = state_hash section_start_state in - let stop_hash = Some (aux start) in - let* check = - Game.check_dissection - (Some start) - section_start_at - stop_hash - section_stop_at - dissection - in - return (Result.to_option check = Some ()) - -let testDissection = - let open QCheck2 in - [ - Test.make - ~name:"randomVPN" - Gen.(triple (list_size small_int (int_range 0 100)) small_int small_int) - (fun (initial_prog, start_at, length) -> - assume - (start_at >= 0 && length > 1 - && List.length initial_prog > start_at + length) ; - let module P = MakeRandomPVM (struct - let initial_prog = initial_prog - end) in - Lwt_main.run @@ test_random_dissection (module P) start_at length); - Test.make - ~name:"count" - Gen.(triple small_int small_int small_int) - (fun (target, start_at, length) -> - assume (start_at >= 0 && length > 1) ; - let module P = MakeCountingPVM (struct - let target = target - end) in - Lwt_main.run @@ test_random_dissection (module P) start_at length); - ] - -let testRandomDissection = - let open QCheck2 in - [ - Test.make - ~name:"randomdissection" - Gen.(pair small_int small_int) - (fun (start_int, length) -> - assume (start_int > 0 && length >= 10) ; - let testing_lwt = - let start_at = tick_of_int_exn start_int in - let stop_at = tick_of_int_exn (start_int + length) in - let start_hash = random_hash () in - let stop_hash = Some (random_hash ()) in - - let* dissection_opt = - random_dissection start_at start_hash stop_at stop_hash - in - let dissection = - match dissection_opt with None -> assert false | Some d -> d - in - let rec aux hash = - let new_hash = Some (random_hash ()) in - if hash = new_hash then aux hash else new_hash - in - let new_hash = aux stop_hash in - let* check = - Game.check_dissection - (Some start_hash) - start_at - new_hash - stop_at - dissection - in - return (Result.to_option check = Some ()) - in - Lwt_main.run testing_lwt); - ] - -let () = - Alcotest.run - "Refutation Game" - [ - ("Dissection tests", qcheck_wrap testDissection); - ("Random dissection", qcheck_wrap testRandomDissection); - ( "RandomPVM", - qcheck_wrap - [ - testing_randomPVM perfect_perfect "perfect-perfect"; - testing_randomPVM random_random "random-random"; - testing_randomPVM random_perfect "random-perfect"; - testing_randomPVM perfect_random "perfect-random"; - ] ); - ( "CountingPVM", - qcheck_wrap - [ - testing_countPVM perfect_perfect "perfect-perfect"; - testing_countPVM random_random "random-random"; - testing_countPVM random_perfect "random-perfect"; - testing_countPVM perfect_random "perfect-random"; - ] ); - ( "ArithPVM", - qcheck_wrap - [ - testing_arith perfect_perfect "perfect-perfect"; - testing_arith random_random "random-random"; - testing_arith random_perfect "random-perfect"; - testing_arith perfect_random "perfect-random"; - ] ); - ] diff --git a/src/proto_014_PtKathma/lib_sc_rollup/dune b/src/proto_014_PtKathma/lib_sc_rollup/dune deleted file mode 100644 index fcc36eef2c75daa574f91cf98a36dbe51bc509c0..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/lib_sc_rollup/dune +++ /dev/null @@ -1,23 +0,0 @@ -; This file was automatically generated, do not edit. -; Edit file manifest/main.ml instead. - -(library - (name tezos_sc_rollup_014_PtKathma) - (public_name tezos-sc-rollup-014-PtKathma) - (instrumentation (backend bisect_ppx)) - (libraries - tezos-base - tezos-protocol-014-PtKathma - tezos-protocol-plugin-014-PtKathma - tezos-protocol-014-PtKathma.parameters - tezos-rpc) - (inline_tests (flags -verbose) (modes native)) - (preprocess (pps ppx_expect)) - (library_flags (:standard -linkall)) - (flags - (:standard) - -open Tezos_base.TzPervasives - -open Tezos_protocol_014_PtKathma - -open Tezos_protocol_plugin_014_PtKathma - -open Tezos_protocol_014_PtKathma_parameters - -open Tezos_rpc)) diff --git a/src/proto_014_PtKathma/lib_sc_rollup/sc_rollup_services.ml b/src/proto_014_PtKathma/lib_sc_rollup/sc_rollup_services.ml deleted file mode 100644 index ce18348721e66c500da9d4053048e9e734417121..0000000000000000000000000000000000000000 --- a/src/proto_014_PtKathma/lib_sc_rollup/sc_rollup_services.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_rpc -open Protocol -open Alpha_context - -(* We distinguish RPC endpoints served by the rollup node into `global` and - `local`. The difference between the two lies in whether the responses - given by different rollup nodes in the same state (see below for an - exact definition) must be the same (in the case of global endpoints) - or can differ (in the case of local endpoints). - - More formally, two rollup nodes are in the same quiescent state if they are - subscribed to the same rollup address, and have processed the same set of - heads from the layer1. We only consider quiescent states, that is those - where rollup nodes are not actively processing a head received from layer1. - - Examples of global endpoints are `current_inbox` and - `last_stored_commitment`, as the responses returned by these endpoints - is expected to be consistent across rollup nodes in the same state. - - An example of local endpoint is `last_published_commitments`, as two rollup - nodes in the same state may either publish or not publish a commitment, - according to whether its inbox level is below the inbox level of the - last cemented commitment at the time they tried to publish the commitment. - See below for a more detailed explanation. -*) - -let commitment_with_hash_and_level_encoding = - Data_encoding.( - obj3 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) - (opt "published_at_level" Raw_level.encoding)) - -module Global = struct - open RPC_path - - let prefix = root / "global" - - let sc_rollup_address () = - RPC_service.get_service - ~description:"Smart-contract rollup address" - ~query:RPC_query.empty - ~output:Sc_rollup.Address.encoding - (prefix / "sc_rollup_address") - - let current_tezos_head () = - RPC_service.get_service - ~description:"Tezos head known to the smart-contract rollup node" - ~query:RPC_query.empty - ~output:(Data_encoding.option Block_hash.encoding) - (prefix / "tezos_head") - - let current_tezos_level () = - RPC_service.get_service - ~description:"Tezos level known to the smart-contract rollup node" - ~query:RPC_query.empty - ~output:(Data_encoding.option Data_encoding.int32) - (prefix / "tezos_level") - - let current_inbox () = - RPC_service.get_service - ~description:"Current inbox" - ~query:RPC_query.empty - ~output:Sc_rollup.Inbox.encoding - (prefix / "inbox") - - let current_ticks () = - RPC_service.get_service - ~description:"Current number of ticks for current level" - ~query:RPC_query.empty - ~output:Data_encoding.z - (prefix / "ticks") - - let current_total_ticks () = - RPC_service.get_service - ~description:"Current total number of ticks" - ~query:RPC_query.empty - ~output:Sc_rollup.Tick.encoding - (prefix / "total_ticks") - - let current_num_messages () = - RPC_service.get_service - ~description:"Current number of messages" - ~query:RPC_query.empty - ~output:Data_encoding.z - (prefix / "current_num_messages") - - let current_state_hash () = - RPC_service.get_service - ~description:"Current state hash" - ~query:RPC_query.empty - ~output:Sc_rollup.State_hash.encoding - (prefix / "state_hash") - - let last_stored_commitment () = - RPC_service.get_service - ~description:"Last commitment computed by the node" - ~query:RPC_query.empty - ~output:(Data_encoding.option commitment_with_hash_and_level_encoding) - (prefix / "last_stored_commitment") - - let current_status () = - RPC_service.get_service - ~description:"Current PVM status" - ~query:RPC_query.empty - ~output:Data_encoding.string - (prefix / "status") - - let dal_slot_subscriptions () = - RPC_service.get_service - ~description:"Current data availability layer slot subscriptions" - ~query:RPC_query.empty - ~output:(Data_encoding.list Dal.Slot_index.encoding) - (prefix / "dal" / "slots") -end - -module Local = struct - open RPC_path - - let prefix = root / "local" - - (* commitments are published only if their inbox level is above the last - cemented commitment level inbox level. Because this information is - fetched from the head of the tezos node to which the rollup node is - connected, it is possible that two rollup nodes that have processed - the same set of heads, but whose corresponding layer1 node has - different information about the last cemented commitment, will - decide to publish and not to publish a commitment, respectively. - As a consequence, the results returned by the endpoint below - in the rollup node will be different. - *) - let last_published_commitment () = - RPC_service.get_service - ~description:"Last commitment published by the node" - ~query:RPC_query.empty - ~output:(Data_encoding.option commitment_with_hash_and_level_encoding) - (prefix / "last_published_commitment") -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_client/RPC.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_client/RPC.ml deleted file mode 100644 index d1d9721017ebb30641f82f6d1bfa4727c60b3cd4..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_client/RPC.ml +++ /dev/null @@ -1,37 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Configuration - -let call (cctxt : #sc_client_context) = cctxt#call_service - -let get_sc_rollup_addresses_command cctxt = - call cctxt (Sc_rollup_services.Global.sc_rollup_address ()) () () () - -let get_state_value_command cctxt key = - call cctxt (Sc_rollup_services.Local.current_state_value ()) () {key} () - -let get_outbox_proof cctxt serialized_output = - call cctxt (Sc_rollup_services.Global.outbox_proof ()) () serialized_output () diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_client/commands.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_client/commands.ml deleted file mode 100644 index 7372a84a6e70c21c8e56da27d905636359707ff4..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_client/commands.ml +++ /dev/null @@ -1,236 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 Protocol.Alpha_context - -let get_sc_rollup_addresses_command () = - command - ~desc: - "Retrieve the smart-contract rollup address the node is interacting with." - no_options - (fixed ["get"; "sc"; "rollup"; "address"]) - (fun () (cctxt : #Configuration.sc_client_context) -> - RPC.get_sc_rollup_addresses_command cctxt >>=? fun addr -> - cctxt#message "@[%a@]" Sc_rollup.Address.pp addr >>= fun () -> return_unit) - -let get_state_value_command () = - command - ~desc:"Observe a key in the PVM state." - no_options - (prefixes ["get"; "state"; "value"; "for"] - @@ string ~name:"key" ~desc:"The key of the state value" - @@ stop) - (fun () key (cctxt : #Configuration.sc_client_context) -> - RPC.get_state_value_command cctxt key >>=? fun bytes -> - cctxt#message "@[%S@]" (String.of_bytes bytes) >>= fun () -> return_unit) - -(** [display_answer cctxt answer] prints an RPC answer. *) -let display_answer (cctxt : #Configuration.sc_client_context) : - RPC_context.generic_call_result -> unit Lwt.t = function - | `Json (`Ok json) -> cctxt#answer "%a" Json_repr.(pp (module Ezjsonm)) json - | `Binary (`Ok binary) -> cctxt#answer "%a" Hex.pp (Hex.of_string binary) - | `Json (`Error (Some error)) -> - cctxt#error - "@[Command failed: @[%a@]@]@." - (Format.pp_print_list Error_monad.pp) - (Data_encoding.Json.destruct - (Data_encoding.list Error_monad.error_encoding) - error) - | `Binary (`Error (Some error)) -> ( - match Data_encoding.Binary.of_string Error_monad.trace_encoding error with - | Ok trace -> - cctxt#error - "@[Command failed: @[%a@]@]@." - Error_monad.pp_print_trace - trace - | Error msg -> - cctxt#error - "@[Error whilst decoding the server response: @[%a@]@]@." - Data_encoding.Binary.pp_read_error - msg) - | `Json (`Not_found _) | `Binary (`Not_found _) | `Other (_, `Not_found _) -> - cctxt#error "No service found at this URL\n%!" - | `Json (`Gone _) | `Binary (`Gone _) | `Other (_, `Gone _) -> - cctxt#error - "Requested data concerns a pruned block and target resource is no \ - longer available\n\ - %!" - | `Json (`Unauthorized _) - | `Binary (`Unauthorized _) - | `Other (_, `Unauthorized _) -> - cctxt#error "@[[HTTP 403] Access denied to: %a@]@." Uri.pp cctxt#base - | _ -> cctxt#error "Unexpected server answer\n%!" - -let get_output_proof () = - let parse_transactions transactions = - let json = Ezjsonm.from_string transactions in - let open Ezjsonm in - let open Sc_rollup.Outbox.Message in - let open Lwt_result_syntax in - let transaction json = - let destination = - find json ["destination"] |> get_string - |> Protocol.Contract_hash.of_b58check_exn - in - let entrypoint = - try - find json ["entrypoint"] |> get_string - |> Entrypoint.of_string_strict_exn - with Not_found -> Entrypoint.default - in - let*? parameters = - Tezos_micheline.Micheline_parser.no_parsing_error - @@ (find json ["parameters"] |> get_string - |> Michelson_v1_parser.parse_expression) - in - let unparsed_parameters = parameters.expanded in - return @@ {destination; entrypoint; unparsed_parameters} - in - match json with - | `A messages -> - let* transactions = List.map_es transaction messages in - return @@ Atomic_transaction_batch {transactions} - | `O _ -> - let* transaction = transaction json in - return @@ Atomic_transaction_batch {transactions = [transaction]} - | _ -> - failwith - "An outbox message must be either a single transaction or a list of \ - transactions." - in - - command - ~desc:"Ask the rollup node for an output proof." - no_options - (prefixes ["get"; "proof"; "for"; "message"] - @@ string ~name:"index" ~desc:"The index of the message in the outbox" - @@ prefixes ["of"; "outbox"; "at"; "level"] - @@ string - ~name:"level" - ~desc:"The level of the rollup outbox where the message is available" - @@ prefixes ["transferring"] - @@ string - ~name:"transactions" - ~desc:"A JSON description of the transactions" - @@ stop) - (fun () index level transactions (cctxt : #Configuration.sc_client_context) -> - let open Lwt_result_syntax in - let* message = parse_transactions transactions in - let output = - Protocol.Alpha_context.Sc_rollup. - { - message_index = Z.of_string index; - outbox_level = Raw_level.of_int32_exn (Int32.of_string level); - message; - } - in - RPC.get_outbox_proof cctxt output >>=? fun (commitment_hash, proof) -> - cctxt#message - {|@[{ "proof" : "0x%a", "commitment_hash" : "%a"@]}|} - Hex.pp - (Hex.of_string proof) - Protocol.Alpha_context.Sc_rollup.Commitment.Hash.pp - commitment_hash - >>= fun () -> return_unit) - -(** [call_get cctxt raw_url] executes a GET RPC call against the [raw_url]. *) -let call_get (cctxt : #Configuration.sc_client_context) raw_url = - let open Lwt_result_syntax in - let meth = `GET in - let uri = Uri.of_string raw_url in - let* answer = cctxt#generic_media_type_call meth uri in - let*! () = display_answer cctxt answer in - return_unit - -let rpc_get_command = - command - ~desc:"Call an RPC with the GET method." - no_options - (prefixes ["rpc"; "get"] @@ string ~name:"url" ~desc:"the RPC URL" @@ stop) - (fun () url cctxt -> call_get cctxt url) - -module Keys = struct - open Tezos_client_base.Client_keys - - let generate_keys () = - command - ~desc:"Generate a pair of keys." - (args1 (Secret_key.force_switch ())) - (prefixes ["gen"; "unencrypted"; "keys"] - @@ Aggregate_alias.Secret_key.fresh_alias_param @@ stop) - (fun force name (cctxt : #Configuration.sc_client_context) -> - Client_keys_commands.Bls_commands.generate_keys - ~force - ~encrypted:false - name - cctxt) - - let list_keys () = - command - ~desc:"List keys." - no_options - (prefixes ["list"; "keys"] @@ stop) - (fun () (cctxt : #Configuration.sc_client_context) -> - Client_keys_commands.Bls_commands.list_keys cctxt) - - let show_address () = - command - ~desc:"Show the keys associated with an account." - no_options - (prefixes ["show"; "address"] - @@ Aggregate_alias.Public_key_hash.alias_param @@ stop) - (fun () (name, _pkh) (cctxt : #Configuration.sc_client_context) -> - Client_keys_commands.Bls_commands.show_address - ~show_private:true - name - cctxt) - - let import_secret_key () = - command - ~desc:"Add a secret key to the wallet." - (args1 (Aggregate_alias.Secret_key.force_switch ())) - (prefixes ["import"; "secret"; "key"] - @@ Aggregate_alias.Secret_key.fresh_alias_param @@ aggregate_sk_uri_param - @@ stop) - (fun force name sk_uri (cctxt : #Configuration.sc_client_context) -> - Client_keys_commands.Bls_commands.import_secret_key - ~force - name - sk_uri - cctxt) -end - -let all () = - [ - get_sc_rollup_addresses_command (); - get_state_value_command (); - get_output_proof (); - rpc_get_command; - Keys.generate_keys (); - Keys.list_keys (); - Keys.show_address (); - Keys.import_secret_key (); - ] diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_client/commands.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_client/commands.mli deleted file mode 100644 index 32de9f752b330b75d04bd8dbe7fe69a72d21c3a6..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_client/commands.mli +++ /dev/null @@ -1,29 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 ()] is the list of commands recognized by the smart-contract - rollup client. These commands may depend on the client - configuration. *) -val all : unit -> Configuration.sc_client_context Clic.command list diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_client/configuration.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_client/configuration.ml deleted file mode 100644 index 0de3f0b092ae18b710df38248925cf63af15b33a..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_client/configuration.ml +++ /dev/null @@ -1,113 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 Lwt_result_syntax -module Base = Tezos_client_base - -type t = {base_dir : string; endpoint : Uri.t} - -let default_base_dir = - Filename.concat (Sys.getenv "HOME") ".tezos-sc-rollup-client" - -let default_endpoint = "http://localhost:8932" - -let default = - {base_dir = default_base_dir; endpoint = Uri.of_string default_endpoint} - -let valid_endpoint _configuration s = - let endpoint = Uri.of_string s in - match (Uri.scheme endpoint, Uri.query endpoint, Uri.fragment endpoint) with - | Some ("http" | "https"), [], None -> return endpoint - | _ -> failwith "Endpoint should be of the form http[s]://address:port" - -let endpoint_arg () = - arg - ~long:"endpoint" - ~short:'E' - ~placeholder:"uri" - ~doc: - (Printf.sprintf - "endpoint of the sc rollup node; e.g. '%s'" - default_endpoint) - @@ parameter valid_endpoint - -let valid_base_dir _configuration base_dir = - if not (Sys.file_exists base_dir && Sys.is_directory base_dir) then - failwith "%s does not seem to be an existing directory" base_dir - else return base_dir - -let base_dir_arg () = - arg - ~long:"base-dir" - ~short:'d' - ~placeholder:"path" - ~doc: - (Format.asprintf - "@[@[<2>Tezos smart-contract rollup client data directory@,\ - The directory where the Tezos smart-contract rollup client stores \ - its data.@,\ - If absent, its value defaults to %s@]@]@." - default_base_dir) - (parameter valid_base_dir) - -let global_options () = Clic.args2 (base_dir_arg ()) (endpoint_arg ()) - -let make (base_dir, endpoint) = - { - base_dir = Option.value base_dir ~default:default_base_dir; - endpoint = Option.value endpoint ~default:(Uri.of_string default_endpoint); - } - -let parse argv = - let* opts, argv = - Clic.parse_global_options (global_options ()) default argv - in - return (make opts, argv) - -class type sc_client_context = - object - inherit Base.Client_context.io_wallet - - inherit RPC_context.generic - end - -class unix_sc_client_context ~base_dir ~password_filename ~rpc_config : - sc_client_context = - object - inherit Client_context_unix.unix_io_wallet ~base_dir ~password_filename - - inherit - Tezos_rpc_http_client_unix.RPC_client_unix.http_ctxt - rpc_config - (Tezos_rpc_http.Media_type.Command_line.of_command_line - rpc_config.media_type) - end - -let make_unix_client_context {base_dir; endpoint} = - let rpc_config = - {Tezos_rpc_http_client_unix.RPC_client_unix.default_config with endpoint} - in - new unix_sc_client_context ~base_dir ~rpc_config ~password_filename:None diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_client/configuration.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_client/configuration.mli deleted file mode 100644 index 9aebfc3ba4b741d568d529020d5e650b630004d5..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_client/configuration.mli +++ /dev/null @@ -1,64 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 configuration. *) -type t = private { - base_dir : string; - (** [base_dir] is a directory where client user data is stored. *) - endpoint : Uri.t; - (** [endpoint] is used to communicate with the smart-contract rollup - node. *) -} - -(** [parse argv] parses command-line arguments to return - [(configuration, argv')] where [configuration] is deduced from the - command-line arguments and [argv'] is the rest of the command-line - arguments that have no meaning relatively to [Configuration]. *) -val parse : string list -> (t * string list) tzresult Lwt.t - -(** [global_options ()] returns the list of options that have an - influence on the configuration. *) -val global_options : unit -> (string option * Uri.t option, 'a) Clic.options - -(** Instance of [Tezos_client_base.Client_context] that only handles IOs and - RPCs. Can be used for keys and RPCs related commands. *) -class type sc_client_context = - object - inherit Tezos_client_base.Client_context.io_wallet - - inherit RPC_context.generic - end - -(** Instance of [sc_client_context] for linux systems. Relies on - [Tezos_rpc_http_client_unix]. *) -class unix_sc_client_context : - base_dir:string - -> password_filename:string option - -> rpc_config:Tezos_rpc_http_client_unix.RPC_client_unix.config - -> sc_client_context - -(** [make_unix_client_context config] generates a unix_sc_client_context from - the client configuration. *) -val make_unix_client_context : t -> unix_sc_client_context diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_client/dune b/src/proto_015_PtLimaPt/bin_sc_rollup_client/dune deleted file mode 100644 index 6c6f6693d4817b242f4da9e76481393568336c1c..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_client/dune +++ /dev/null @@ -1,36 +0,0 @@ -; This file was automatically generated, do not edit. -; Edit file manifest/main.ml instead. - -(executable - (name main_sc_rollup_client_015_PtLimaPt) - (public_name octez-sc-rollup-client-PtLimaPt) - (package octez-sc-rollup-client-PtLimaPt) - (instrumentation (backend bisect_ppx)) - (libraries - tezos-base - tezos-clic - tezos-client-base - tezos-client-015-PtLimaPt - tezos-client-commands - tezos-stdlib-unix - tezos-client-base-unix - tezos-rpc-http - tezos-rpc-http-client-unix - tezos-protocol-015-PtLimaPt - tezos-sc-rollup-015-PtLimaPt - uri) - (link_flags - (:standard) - (:include %{workspace_root}/static-link-flags.sexp)) - (flags - (:standard) - -open Tezos_base.TzPervasives - -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals - -open Tezos_clic - -open Tezos_client_015_PtLimaPt - -open Tezos_client_commands - -open Tezos_stdlib_unix - -open Tezos_client_base_unix - -open Tezos_rpc_http_client_unix - -open Tezos_protocol_015_PtLimaPt - -open Tezos_sc_rollup_015_PtLimaPt)) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_client/main_sc_rollup_client_015_PtLimaPt.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_client/main_sc_rollup_client_015_PtLimaPt.ml deleted file mode 100644 index 5d7ada1f54cee7a1893645f2fab4f1683fea6d5d..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_client/main_sc_rollup_client_015_PtLimaPt.ml +++ /dev/null @@ -1,59 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 executable_name = Filename.basename Sys.executable_name - -let argv () = Array.to_list Sys.argv |> List.tl |> Stdlib.Option.get - -let main () = - Configuration.parse (argv ()) >>=? fun (configuration, argv) -> - let cctxt = Configuration.make_unix_client_context configuration in - Tezos_client_base.Client_keys.register_aggregate_signer - (module Tezos_signer_backends.Unencrypted.Aggregate) ; - Clic.dispatch (Commands.all ()) cctxt argv - -let handle_error = function - | Ok () -> Stdlib.exit 0 - | Error [Clic.Version] -> - let version = Tezos_version.Bin_version.version_string in - Format.printf "%s\n" version ; - Stdlib.exit 0 - | Error [Clic.Help command] -> - Clic.usage - Format.std_formatter - ~executable_name - ~global_options:(Configuration.global_options ()) - (match command with None -> [] | Some c -> [c]) ; - Stdlib.exit 0 - | Error errs -> - Clic.pp_cli_errors - Format.err_formatter - ~executable_name - ~global_options:(Configuration.global_options ()) - ~default:Error_monad.pp - errs ; - Stdlib.exit 1 - -let () = Lwt_main.run (Lwt.catch main fail_with_exn) |> handle_error diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/RPC_server.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/RPC_server.ml deleted file mode 100644 index 50f8f64762ec223c95fdcb63cfeee2415d9a93b4..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/RPC_server.ml +++ /dev/null @@ -1,312 +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_rpc -open Tezos_rpc_http -open Tezos_rpc_http_server -open Protocol - -let get_head store = - let open Lwt_result_syntax in - let*! head = Layer1.current_head_hash store in - match head with None -> failwith "No head" | Some head -> return head - -let get_state_info_exn store = - let open Lwt_result_syntax in - let* head = get_head store in - let*! state = Store.StateInfo.get store head in - return state - -let get_dal_slot_subscriptions_exn store = - let open Lwt_result_syntax in - let* head = get_head store in - let*! slot_subscriptions = Store.Dal_slot_subscriptions.find store head in - match slot_subscriptions with - | None -> failwith "No slot subscriptions" - | Some slot_subscriptions -> return slot_subscriptions - -let get_dal_slots store = - let open Lwt_result_syntax in - let* head = get_head store in - let*! slot_headers = Store.Dal_slots.list_values store ~primary_key:head in - return slot_headers - -let get_dal_confirmed_slots store = - let open Lwt_result_syntax in - let* head = get_head store in - let*! l = Store.Dal_confirmed_slots.list_values store ~primary_key:head in - return l - -let commitment_with_hash commitment = - ( Protocol.Alpha_context.Sc_rollup.Commitment.hash_uncarbonated commitment, - commitment ) - -module Common = struct - let register_current_num_messages store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_num_messages ()) - (fun () () -> - let open Lwt_result_syntax in - let* state_info = get_state_info_exn store in - return state_info.num_messages) - - let register_sc_rollup_address configuration dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.sc_rollup_address ()) - (fun () () -> return @@ configuration.Configuration.sc_rollup_address) - - let register_current_tezos_head store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_tezos_head ()) - (fun () () -> Layer1.current_head_hash store >>= return) - - let register_current_tezos_level store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_tezos_level ()) - (fun () () -> Layer1.current_level store >>= return) - - let register_current_inbox node_ctxt dir = - let open Lwt_result_syntax in - RPC_directory.opt_register0 - dir - (Sc_rollup_services.Global.current_inbox ()) - (fun () () -> - Layer1.current_head_hash node_ctxt.Node_context.store >>= function - | Some head_hash -> - let* inbox = Inbox.inbox_of_hash node_ctxt head_hash in - return_some inbox - | None -> return None) - - let register_current_ticks store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_ticks ()) - (fun () () -> - let open Lwt_result_syntax in - let* state = get_state_info_exn store in - return state.num_ticks) - - let start configuration dir = - let Configuration.{rpc_addr; rpc_port; _} = configuration in - let rpc_addr = P2p_addr.of_string_exn rpc_addr in - let host = Ipaddr.V6.to_string rpc_addr in - let node = `TCP (`Port rpc_port) in - let acl = RPC_server.Acl.default rpc_addr in - Lwt.catch - (fun () -> - RPC_server.launch - ~media_types:Media_type.all_media_types - ~host - ~acl - node - dir - >>= return) - fail_with_exn - - let shutdown = RPC_server.shutdown -end - -module type S = sig - module PVM : Pvm.S - - val shutdown : RPC_server.server -> unit Lwt.t - - val register : Node_context.t -> Configuration.t -> unit RPC_directory.t - - val start : - Node_context.t -> Configuration.t -> RPC_server.server tzresult Lwt.t -end - -module Make (PVM : Pvm.S) : S with module PVM = PVM = struct - include Common - module PVM = PVM - module Outbox = Outbox.Make (PVM) - - let get_context ?block_hash (node_ctxt : Node_context.t) = - let open Lwt_result_syntax in - let* block_hash = - match block_hash with - | None -> get_head node_ctxt.store - | Some block_hash -> return block_hash - in - let* ctxt = Node_context.checkout_context node_ctxt block_hash in - return ctxt - - let get_state ?block_hash (node_ctxt : Node_context.t) = - let open Lwt_result_syntax in - let* ctxt = get_context ?block_hash node_ctxt in - let*! state = PVM.State.find ctxt in - match state with None -> failwith "No state" | Some state -> return state - - let register_current_total_ticks node_ctxt dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_total_ticks ()) - (fun () () -> - let open Lwt_result_syntax in - let* state = get_state node_ctxt in - let*! tick = PVM.get_tick state in - return tick) - - let register_current_state_hash node_ctxt dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_state_hash ()) - (fun () () -> - let open Lwt_result_syntax in - let* state = get_state node_ctxt in - let*! hash = PVM.state_hash state in - return hash) - - let register_current_state_value node_ctxt dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Local.current_state_value ()) - (fun {key} () -> - let open Lwt_result_syntax in - let* state = get_state node_ctxt in - let path = String.split_on_char '/' key in - let*! value = PVM.State.lookup state path in - match value with - | None -> failwith "No such key in PVM state" - | Some value -> - Format.eprintf "Encoded %S\n@.%!" (Bytes.to_string value) ; - return value) - - let register_last_stored_commitment store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.last_stored_commitment ()) - (fun () () -> - let open Lwt_result_syntax in - let*! commitment_with_hash = - Commitment.last_commitment_with_hash - (module Store.Last_stored_commitment_level) - store - in - return - (commitment_with_hash - |> Option.map (fun (commitment, hash) -> (commitment, hash, None)))) - - let register_last_published_commitment store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Local.last_published_commitment ()) - (fun () () -> - let open Lwt_result_syntax in - let*! result = - let open Lwt_option_syntax in - let* commitment, hash = - Commitment.last_commitment_with_hash - (module Store.Last_published_commitment_level) - store - in - (* The corresponding level in Store.Commitments.published_at_level is - available only when the commitment has been published and included - in a block. *) - let*! published_at_level = - Store.Commitments_published_at_level.find store hash - in - return (commitment, hash, published_at_level) - in - return result) - - let register_current_status node_ctxt dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_status ()) - (fun () () -> - let open Lwt_result_syntax in - let* state = get_state node_ctxt in - let*! status = PVM.get_status state in - return (PVM.string_of_status status)) - - let register_dal_slot_subscriptions store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.dal_slot_subscriptions ()) - (fun () () -> get_dal_slot_subscriptions_exn store) - - let register_dal_slots store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.dal_slots ()) - (fun () () -> get_dal_slots store) - - let register_dal_confirmed_slots store dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.dal_confirmed_slots ()) - (fun () () -> get_dal_confirmed_slots store) - - let register_current_outbox node_ctxt dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.current_outbox ()) - (fun () () -> - let open Lwt_result_syntax in - let store = node_ctxt.Node_context.store in - let*! lcc_level = Store.Last_cemented_commitment_level.get store in - let*! block_hash = - Layer1.hash_of_level - store - (Alpha_context.Raw_level.to_int32 lcc_level) - in - let* state = get_state ~block_hash node_ctxt in - let*! outbox = PVM.get_outbox state in - return outbox) - - let register_outbox_proof node_ctxt dir = - RPC_directory.register0 - dir - (Sc_rollup_services.Global.outbox_proof ()) - (fun output () -> Outbox.proof_of_output node_ctxt output) - - let register (node_ctxt : Node_context.t) configuration = - RPC_directory.empty - |> register_sc_rollup_address configuration - |> register_current_tezos_head node_ctxt.store - |> register_current_inbox node_ctxt - |> register_current_ticks node_ctxt.store - |> register_current_total_ticks node_ctxt - |> register_current_num_messages node_ctxt.store - |> register_current_state_hash node_ctxt - |> register_current_state_value node_ctxt - |> register_current_status node_ctxt - |> register_last_stored_commitment node_ctxt.store - |> register_last_published_commitment node_ctxt.store - |> register_dal_slot_subscriptions node_ctxt.store - |> register_dal_slots node_ctxt.store - |> register_dal_confirmed_slots node_ctxt.store - |> register_current_outbox node_ctxt - |> register_outbox_proof node_ctxt - - let start node_ctxt configuration = - Common.start configuration (register node_ctxt configuration) -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/arith_pvm.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/arith_pvm.ml deleted file mode 100644 index 84325edd3fc01c4740a5e4cc8701fbaba92db1e6..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/arith_pvm.ml +++ /dev/null @@ -1,60 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 manifests the proof format used by the Arith PVM as defined by - the Layer 1 implementation for it. - - It is imperative that this is aligned with the protocol's implementation. -*) -module Arith_proof_format = - Context.Proof - (struct - include Sc_rollup.State_hash - - let of_context_hash = Sc_rollup.State_hash.context_hash_to_state_hash - end) - (struct - let proof_encoding = - Tezos_context_merkle_proof_encoding.Merkle_proof_encoding.V2.Tree32 - .tree_proof_encoding - end) - -module Impl : Pvm.S = struct - include Sc_rollup.ArithPVM.Make (Arith_proof_format) - module State = Context.PVMState - - let string_of_status status = - match status with - | Halted -> "Halted" - | Waiting_for_input_message -> "Waiting for input message" - | Waiting_for_reveal -> "Waiting for reveal" - | Parsing -> "Parsing" - | Evaluating -> "Evaluating" -end - -include Impl diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment.ml deleted file mode 100644 index 439d9fb3b72aadf09de170f617ccc6a5979e7b31..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment.ml +++ /dev/null @@ -1,430 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 rollup node stores and publishes commitments for the PVM every - [Constants.sc_rollup_commitment_period_in_blocks] levels. - - Every time a finalized block is processed by the rollup node, the latter - determines whether the last commitment that the node has produced referred - to [sc_rollup.commitment_period_in_blocks] blocks earlier. For mainnet, - [sc_rollup.commitment_period_in_blocks = 30]. In this case, it computes and - stores a new commitment in a level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) - -open Protocol -open Alpha_context - -module type Mutable_level_store = - Store_utils.Mutable_value with type value = Raw_level.t - -(* We persist the number of ticks to be included in the - next commitment on disk, in a map that is indexed by - inbox level. Note that we do not risk to increase - these counters when the wrong branch is tracked by the rollup - node, as only finalized heads are processed to build commitments. -*) -module Number_of_ticks = Store_utils.Make_append_only_map (struct - let path = ["commitments"; "in_progress"; "number_of_ticks"] - - (* We only access the number of ticks for either the - current or previous level being processed by the - commitment module. Therefore, by keeping the - last two entries in memory, we ensure that - the information about ticks is always recovered - from the main memory. *) - let keep_last_n_entries_in_memory = 2 - - type key = Raw_level.t - - let string_of_key l = Int32.to_string @@ Raw_level.to_int32 l - - type value = Z.t - - let value_encoding = Data_encoding.z -end) - -let sc_rollup_commitment_period node_ctxt = - Int32.of_int - @@ node_ctxt.Node_context.protocol_constants.parametric.sc_rollup - .commitment_period_in_blocks - -let sc_rollup_challenge_window node_ctxt = - Int32.of_int - node_ctxt.Node_context.protocol_constants.parametric.sc_rollup - .challenge_window_in_blocks - -let last_commitment_level (module Last_commitment_level : Mutable_level_store) - store = - Last_commitment_level.find store - -let last_commitment_with_hash - (module Last_commitment_level : Mutable_level_store) store = - let open Lwt_option_syntax in - let* last_commitment_level = - last_commitment_level (module Last_commitment_level) store - in - let*! commitment_with_hash = - Store.Commitments.get store last_commitment_level - in - return commitment_with_hash - -let next_commitment_level node_ctxt - (module Last_commitment_level : Mutable_level_store) = - let open Lwt_syntax in - let+ last_commitment_level_opt = - last_commitment_level - (module Last_commitment_level) - node_ctxt.Node_context.store - in - let last_commitment_level = - Option.value last_commitment_level_opt ~default:node_ctxt.genesis_info.level - in - Raw_level.of_int32 - @@ Int32.add - (Raw_level.to_int32 last_commitment_level) - (sc_rollup_commitment_period node_ctxt) - -let last_commitment_hash node_ctxt - (module Last_commitment_level : Mutable_level_store) = - let open Lwt_syntax in - let+ last_commitment = - last_commitment_with_hash - (module Last_commitment_level) - node_ctxt.Node_context.store - in - match last_commitment with - | Some (_commitment, hash) -> hash - | None -> node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash - -let must_store_commitment node_ctxt current_level = - let open Lwt_result_syntax in - let+ next_commitment_level = - next_commitment_level node_ctxt (module Store.Last_stored_commitment_level) - in - - Raw_level.equal current_level next_commitment_level - -let update_last_stored_commitment store (commitment : Sc_rollup.Commitment.t) = - let open Lwt_syntax in - let commitment_hash = Sc_rollup.Commitment.hash_uncarbonated commitment in - let inbox_level = commitment.inbox_level in - let* lcc_level = Store.Last_cemented_commitment_level.get store in - (* Do not change the order of these two operations. This guarantees that - whenever `Store.Last_stored_commitment_level.get` returns `Some hash`, - then the call to `Store.Commitments.get hash` will succeed. - *) - let* () = - Store.Commitments.add store inbox_level (commitment, commitment_hash) - in - let* () = Store.Last_stored_commitment_level.set store inbox_level in - let* () = Commitment_event.commitment_stored commitment_hash commitment in - if commitment.inbox_level <= lcc_level then - Commitment_event.commitment_will_not_be_published lcc_level commitment - else return () - -module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct - module PVM = PVM - - let build_commitment node_ctxt block_hash = - let open Lwt_result_syntax in - let lsc = - (module Store.Last_stored_commitment_level : Mutable_level_store) - in - let*! predecessor = last_commitment_hash node_ctxt lsc in - let* inbox_level = - Lwt.map Environment.wrap_tzresult @@ next_commitment_level node_ctxt lsc - in - let* ctxt = Node_context.checkout_context node_ctxt block_hash in - let*! pvm_state = PVM.State.find ctxt in - let* compressed_state = - match pvm_state with - | Some pvm_state -> - let*! hash = PVM.state_hash pvm_state in - return hash - | None -> - failwith - "PVM state for block hash not available %s" - (Block_hash.to_string block_hash) - in - let*! number_of_ticks = Number_of_ticks.get node_ctxt.store inbox_level in - let+ number_of_ticks = - match - Sc_rollup.Number_of_ticks.of_value @@ Z.to_int64 number_of_ticks - with - | Some number_of_ticks -> return number_of_ticks - | None -> - failwith "Invalid number of ticks %s" (Z.to_string number_of_ticks) - in - Sc_rollup.Commitment. - {predecessor; inbox_level; number_of_ticks; compressed_state} - - let store_commitment_if_necessary node_ctxt current_level block_hash = - let open Lwt_result_syntax in - let* must_store_commitment = - Lwt.map Environment.wrap_tzresult - @@ must_store_commitment node_ctxt current_level - in - if must_store_commitment then - let*! () = Commitment_event.compute_commitment block_hash current_level in - let* commitment = build_commitment node_ctxt block_hash in - let*! () = update_last_stored_commitment node_ctxt.store commitment in - return_unit - else return_unit - - let update_ticks (node_ctxt : Node_context.t) current_level block_hash = - let open Lwt_result_syntax in - let*! last_stored_commitment_level_opt = - last_commitment_level - (module Store.Last_stored_commitment_level) - node_ctxt.store - in - let last_stored_commitment_level = - Option.value - ~default:node_ctxt.genesis_info.level - last_stored_commitment_level_opt - in - let*! previous_level_num_ticks = - match Raw_level.pred current_level with - | None -> - (* This happens if the current_level is zero: it is safe to assume - that there are 0 ticks computed so far. *) - Lwt.return Z.zero - | Some level -> - if Raw_level.(level = last_stored_commitment_level) then - (* We are at the first level of a new commitment, so the initial amount - of ticks should be 0. *) - Lwt.return Z.zero - else if Raw_level.(level < node_ctxt.genesis_info.level) then - (* If the previous level was before the genesis level, then the - number of ticks at that level should be 0. *) - Lwt.return Z.zero - else - (* Otherwise we need to increment the number of ticks from the number - of ticks for the previous level. The number of ticks for such a - level should be in the store, otherwise the state of the rollup node - is corrupted. *) - Number_of_ticks.get node_ctxt.store level - in - let*! {num_ticks; _} = Store.StateInfo.get node_ctxt.store block_hash in - Number_of_ticks.add - node_ctxt.store - current_level - (Z.add previous_level_num_ticks num_ticks) - - let process_head (node_ctxt : Node_context.t) Layer1.(Head {level; hash}) = - let open Lwt_result_syntax in - let current_level = Raw_level.of_int32_exn level in - let*! () = update_ticks node_ctxt current_level hash in - store_commitment_if_necessary node_ctxt current_level hash - - let sync_last_cemented_commitment_hash_with_level - ({cctxt; rollup_address; store; _} : Node_context.t) = - let open Lwt_result_syntax in - let* hash, inbox_level = - Plugin.RPC.Sc_rollup.last_cemented_commitment_hash_with_level - cctxt - (cctxt#chain, cctxt#block) - rollup_address - in - let*! () = Store.Last_cemented_commitment_level.set store inbox_level in - let*! () = Store.Last_cemented_commitment_hash.set store hash in - let*! () = - Commitment_event.last_cemented_commitment_updated hash inbox_level - in - return_unit - - let get_commitment_and_publish ~check_lcc_hash - ({store; _} as node_ctxt : Node_context.t) next_level_to_publish = - let open Lwt_result_syntax in - let*! is_commitment_available = - Store.Commitments.mem store next_level_to_publish - in - if is_commitment_available then - let*! commitment, _commitment_hash = - Store.Commitments.get store next_level_to_publish - in - let* () = - if check_lcc_hash then - let open Lwt_result_syntax in - let*! lcc_hash = Store.Last_cemented_commitment_hash.get store in - if Sc_rollup.Commitment.Hash.equal lcc_hash commitment.predecessor - then return () - else - let*! () = - Commitment_event.commitment_parent_is_not_lcc - commitment.inbox_level - commitment.predecessor - lcc_hash - in - tzfail - (Sc_rollup_node_errors.Commitment_predecessor_should_be_LCC - commitment) - else return_unit - in - let operator = Node_context.get_operator node_ctxt Publish in - match operator with - | None -> - (* Configured to not publish commitments *) - return_unit - | Some source -> - let publish_operation = - Sc_rollup_publish {rollup = node_ctxt.rollup_address; commitment} - in - let* () = Injector.add_pending_operation ~source publish_operation in - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3462 - Decouple commitments from head processing - - Move the following, in a part where we know the operation is - included. *) - let*! () = - Store.Last_published_commitment_level.set - store - commitment.inbox_level - in - return_unit - else return_unit - - let publish_commitment node_ctxt = - let open Lwt_result_syntax in - (* Check level of next publishable commitment and avoid publishing if it is - on or before the last cemented commitment. - *) - let* next_lcc_level = - Lwt.map Environment.wrap_tzresult - @@ next_commitment_level - node_ctxt - (module Store.Last_cemented_commitment_level) - in - let* next_publishable_level = - Lwt.map Environment.wrap_tzresult - @@ next_commitment_level - node_ctxt - (module Store.Last_published_commitment_level) - in - let check_lcc_hash, level_to_publish = - if Raw_level.(next_publishable_level < next_lcc_level) then - (* - - This situation can happen if the rollup node has been - shutdown and the rollup has been progressing in the - meantime. In that case, the rollup node must wait to reach - [lcc_level + commitment_frequency] to publish the - commitment. ([lcc_level] is a multiple of - commitment_frequency.) - - We need to check that the published commitment comes - immediately after the last cemented commitment, otherwise - that's an invalid commitment. - - *) - (true, next_lcc_level) - else (false, next_publishable_level) - in - get_commitment_and_publish node_ctxt level_to_publish ~check_lcc_hash - - let earliest_cementing_level node_ctxt commitment_hash = - let open Lwt_option_syntax in - let+ published_at_level = - Store.Commitments_published_at_level.find - node_ctxt.Node_context.store - commitment_hash - in - Int32.add - (Raw_level.to_int32 published_at_level) - (sc_rollup_challenge_window node_ctxt) - - let can_be_cemented node_ctxt earliest_cementing_level head_level - commitment_hash = - let {Node_context.cctxt; rollup_address; _} = node_ctxt in - let open Lwt_result_syntax in - if earliest_cementing_level <= head_level then - Plugin.RPC.Sc_rollup.can_be_cemented - cctxt - (cctxt#chain, cctxt#block) - rollup_address - commitment_hash - () - else return_false - - let cement_commitment (node_ctxt : Node_context.t) commitment_hash = - let open Lwt_result_syntax in - let operator = Node_context.get_operator node_ctxt Cement in - match operator with - | None -> - (* Configured to not cement commitments *) - return_unit - | Some source -> - let cement_operation = - Sc_rollup_cement - {rollup = node_ctxt.rollup_address; commitment = commitment_hash} - in - Injector.add_pending_operation ~source cement_operation - - let cement_commitment_if_possible node_ctxt - (Layer1.Head {level = head_level; _}) = - let open Lwt_result_syntax in - let* next_level_to_cement = - Lwt.map Environment.wrap_tzresult - @@ next_commitment_level - node_ctxt - (module Store.Last_cemented_commitment_level) - in - let*! commitment_with_hash = - Store.Commitments.find node_ctxt.store next_level_to_cement - in - match commitment_with_hash with - (* If `commitment_with_hash` is defined, the commitment to be cemented has - been stored but not necessarily published by the rollup node. *) - | Some (_commitment, commitment_hash) -> ( - let*! earliest_cementing_level = - earliest_cementing_level node_ctxt commitment_hash - in - match earliest_cementing_level with - (* If `earliest_cementing_level` is well defined, then the rollup node - has previously published `commitment`, which means that the rollup - is indirectly staked on it. *) - | Some earliest_cementing_level -> - let* green_flag = - can_be_cemented - node_ctxt - earliest_cementing_level - head_level - commitment_hash - in - if green_flag then cement_commitment node_ctxt commitment_hash - else return () - | None -> return ()) - | None -> return () - - let start () = Commitment_event.starting () -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment.mli deleted file mode 100644 index 0878492faf7cfdd1b26efd45845de58a338ac5e5..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment.mli +++ /dev/null @@ -1,62 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 rollup node stores and publishes commitments for the PVM - every 20 levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to 20 blocks earlier. In this case, it - computes and stores a new commitment in a level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) - -open Protocol.Alpha_context - -module type Mutable_level_store = - Store_utils.Mutable_value with type value = Raw_level.t - -(** [last_commitment_with_hash (module Last_level_module: Mutable_level_store) store] - returns the last commitment and relative hash - stored according to the value of level indicated by - [module Last_level_module]. If no commitment has been stored for the - level indicated by [module Last_level_module], then None is returned. - Two possible implementations for [module Last_level_module] are - [Store.Last_published_commitment_level] and - [Store.Last_stored_commitment_level]. - *) - -val last_commitment_with_hash : - (module Mutable_level_store) -> - Store.t -> - (Sc_rollup.Commitment.t * Sc_rollup.Commitment.Hash.t) option Lwt.t - -module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment_event.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment_event.ml deleted file mode 100644 index cabbeba01348a5ed3db415e3860437a47d5cc298..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment_event.ml +++ /dev/null @@ -1,151 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; "commitment"] - - let starting = - declare_0 - ~section - ~name:"sc_rollup_commitment_publisher_starting" - ~msg:"Starting commitment publisher for the smart contract rollup node" - ~level:Notice - () - - let stopping = - declare_0 - ~section - ~name:"sc_rollup_node_commitment_publisher_stopping" - ~msg:"Stopping commitment publisher for the smart contract rollup node" - ~level:Notice - () - - let commitment_will_not_be_published = - declare_5 - ~section - ~name:"sc_rollup_node_commitment_will_not_be_published" - ~msg: - "Commitment will not be published: its inbox level is less or equal \ - than the last cemented commitment level {lcc_level} - predecessor: \ - {predecessor}, inbox_level: {inbox_level}, compressed_state: \ - {compressed_state}, number_of_ticks: {number_of_ticks}" - ~level:Notice - ("lcc_level", Raw_level.encoding) - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) - - let last_cemented_commitment_updated = - declare_2 - ~section - ~name:"sc_rollup_node_lcc_updated" - ~msg: - "Last cemented commitment was updated to hash {hash} at inbox level \ - {level}" - ~level:Notice - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) - - let compute_commitment = - declare_2 - ~section - ~name:"sc_rollup_node_commitment_process_head" - ~msg: - "Computing and storing new commitment for head {head} at level {level}" - ~level:Notice - ("head", Block_hash.encoding) - ("level", Raw_level.encoding) - - let commitment_parent_is_not_lcc = - declare_3 - ~section - ~name:"sc_rollup_commitment_parent_is_not_lcc" - ~msg: - "Trying to publish a commitment at inbox level {level} whose parent is \ - the last cemented commitment, but the commitment's predecessor hash \ - {predecessor_hash} differs from the last cemented commitment hash \ - {lcc_hash}. This is a critical error, and the rollup node will be \ - terminated." - ~level:Fatal - ("level", Raw_level.encoding) - ("predecessor_hash", Sc_rollup.Commitment.Hash.encoding) - ("lcc_hash", Sc_rollup.Commitment.Hash.encoding) - - let commitment_stored = - declare_5 - ~section - ~name:"sc_rollup_node_commitment_stored" - ~msg: - "Commitment {commitment_hash} was stored - predecessor: {predecessor}, \ - inbox_level: {inbox_level}, compressed_state: {compressed_state}, \ - number_of_ticks: {number_of_ticks}" - ~level:Notice - ("commitment_hash", Sc_rollup.Commitment.Hash.encoding) - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) -end - -let starting = Simple.(emit starting) - -let stopping = Simple.(emit stopping) - -open Sc_rollup.Commitment - -let emit_commitment_event f commitment_hash - {predecessor; inbox_level; compressed_state; number_of_ticks} = - Simple.( - emit - f - ( commitment_hash, - predecessor, - inbox_level, - compressed_state, - number_of_ticks )) - -let commitment_will_not_be_published lcc_level - {predecessor; inbox_level; compressed_state; number_of_ticks} = - Simple.( - emit - commitment_will_not_be_published - (lcc_level, predecessor, inbox_level, compressed_state, number_of_ticks)) - -let commitment_stored = emit_commitment_event Simple.commitment_stored - -let last_cemented_commitment_updated head level = - Simple.(emit last_cemented_commitment_updated (head, level)) - -let compute_commitment head level = - Simple.(emit compute_commitment (head, level)) - -let commitment_parent_is_not_lcc level predecessor_hash lcc_hash = - Simple.(emit commitment_parent_is_not_lcc (level, predecessor_hash, lcc_hash)) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment_event.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment_event.mli deleted file mode 100644 index d818ad4d49315f2153c61e7619690f1455bd5e61..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment_event.mli +++ /dev/null @@ -1,67 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 functions that emit the events used for the rollup node - when it is storing and publishing commitments (see {!Commitment}). *) - -open Protocol.Alpha_context - -val starting : unit -> unit Lwt.t - -val stopping : unit -> unit Lwt.t - -(** [commitment_stored commitment_hash commitment] emits the event - that the [commitment] was stored. *) -val commitment_stored : - Sc_rollup.Commitment.Hash.t -> Sc_rollup.Commitment.t -> unit Lwt.t - -(** [commitment_will_not_be_published level commitment] emits the event that - [commitment] will not be published: its inbox level is less or equal than - the last cemented commitment [level]. *) -val commitment_will_not_be_published : - Raw_level.t -> Sc_rollup.Commitment.t -> unit Lwt.t - -(** [last_cemented_commitment_updated hash level] emits the event that the last - cemented commitment was updated to the given [hash] at the given inbox - [level]. *) -val last_cemented_commitment_updated : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t - -(** [commitment_parent_is_not_lcc predecessor_hash last_cemented_commitment_hash] - emits the event that a commitment at the given inbox [level] is being - published, whose parent is the last cemented commitment, but the - commitment's [predecessor_hash] differs from the - [last_cemented_commitment_hash]. - This is a critical error, the rollup node will be terminated. *) -val commitment_parent_is_not_lcc : - Raw_level.t -> - Sc_rollup.Commitment.Hash.t -> - Sc_rollup.Commitment.Hash.t -> - unit Lwt.t - -(** [compute_commitment hash level] emits the event that a new commitment is - being computed and stored for the block of the given [hash] and at the given - [level]. *) -val compute_commitment : Block_hash.t -> Raw_level.t -> unit Lwt.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment_sig.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment_sig.ml deleted file mode 100644 index c5de6d7bda1b47e1958af00181f6ae8bc82198ec..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/commitment_sig.ml +++ /dev/null @@ -1,91 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 rollup node stores and publishes commitments for the PVM - every `Commitment.sc_rollup_commitment_period` levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to `Commitment.sc_rollup_commitment_period` blocks - earlier. In this case, it computes and stores a new commitment in a - level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) -module type S = sig - module PVM : Pvm.S - - (** [process_head node_ctxt head] checks whether a new commitment needs to be - computed and stored, by looking at the level of [head] and checking - whether it is a multiple of `Commitment.sc_rollup_commitment_period` - levels away from [node_ctxt.initial_level]. It uses the functionalities of - [PVM] to compute the hash of to be included in the commitment. *) - val process_head : Node_context.t -> Layer1.head -> unit tzresult Lwt.t - - (** [sync_last_cemented_commitment_hash_with_level node_ctxt] fetches and - stores information about the last cemeneted commitment in the layer1 - chain. *) - val sync_last_cemented_commitment_hash_with_level : - Node_context.t -> unit tzresult Lwt.t - - (** [publish_commitment node_ctxt] publishes the earliest commitment - stored in [store] that has not been published yet, unless its inbox level - is below or equal to the inbox level of the last cemented commitment in - the layer1 chain. In this case, the rollup node checks whether it has - computed a commitment whose inbox level is - [sc_rollup_commitment_period] levels after the inbox level of the last - cemented commitment: - {ul - {li if the commitment is found and its predecessor hash coincides with - the hash of the LCC, the rollup node will try to publish that commitment - instead; } - {li if the commitment is found but its predecessor hash differs from the - hash of the LCC, the rollup node will stop its execution;} - {li if no commitment is found, no action is taken by the rollup node; - in particular, no commitment is published.} - } - *) - val publish_commitment : Node_context.t -> unit tzresult Lwt.t - - (** [cement_commitment_if_possible node_ctxt head] checks whether the next - commitment to be cemented (i.e. whose inbox level is - [sc_rollup_commitment_period] levels after - [Store.Last_cemented_commitment_level store]) can be cemented. In - particular, the request to cement the commitment happens only if the - commitment is stored in [Store.Commitments store], and if - [sc_rollup_challenge_period] levels have passed since when the commitment - was originally published. *) - val cement_commitment_if_possible : - Node_context.t -> Layer1.head -> unit tzresult Lwt.t - - (** [start ()] only emits the event that the commitment manager - for the rollup node has started. *) - val start : unit -> unit Lwt.t -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/components.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/components.ml deleted file mode 100644 index e34b2d798f4aa726bfcf33dfc1b054cde35ede82..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/components.ml +++ /dev/null @@ -1,50 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* Copyright (c) 2022 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. *) -(* *) -(*****************************************************************************) - -module type S = sig - module PVM : Pvm.S - - module Interpreter : Interpreter.S with module PVM = PVM - - module Commitment : Commitment_sig.S with module PVM = PVM - - module RPC_server : RPC_server.S with module PVM = PVM - - module Refutation_game : Refutation_game.S with module PVM = PVM -end - -module Make (PVM : Pvm.S) : S with module PVM = PVM = struct - module PVM = PVM - module Interpreter = Interpreter.Make (PVM) - module Commitment = Commitment.Make (PVM) - module RPC_server = RPC_server.Make (PVM) - module Refutation_game = Refutation_game.Make (Interpreter) -end - -let pvm_of_kind : Protocol.Alpha_context.Sc_rollup.Kind.t -> (module Pvm.S) = - function - | Example_arith -> (module Arith_pvm) - | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/configuration.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/configuration.ml deleted file mode 100644 index c7bd43e4032a3b56e059faff9f188a37cf9dc3a2..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/configuration.ml +++ /dev/null @@ -1,514 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* Copyright (c) 2022 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 Protocol.Alpha_context - -type mode = Observer | Batcher | Maintenance | Operator | Custom - -type purpose = Publish | Add_messages | Cement | Timeout | Refute - -let purposes = [Publish; Add_messages; Cement; Timeout; Refute] - -module Operator_purpose_map = Map.Make (struct - type t = purpose - - let compare = Stdlib.compare -end) - -type operators = Signature.Public_key_hash.t Operator_purpose_map.t - -type fee_parameters = Injection.fee_parameter Operator_purpose_map.t - -type t = { - data_dir : string; - sc_rollup_address : Sc_rollup.t; - sc_rollup_node_operators : operators; - rpc_addr : string; - rpc_port : int; - reconnection_delay : float; - fee_parameters : fee_parameters; - mode : mode; - loser_mode : Loser_mode.t; - dal_node_addr : string; - dal_node_port : int; -} - -let default_data_dir = - Filename.concat (Sys.getenv "HOME") ".tezos-sc-rollup-node" - -let storage_dir = "storage" - -let context_dir = "context" - -let default_storage_dir data_dir = Filename.concat data_dir storage_dir - -let default_context_dir data_dir = Filename.concat data_dir context_dir - -let relative_filename data_dir = Filename.concat data_dir "config.json" - -let filename config = relative_filename config.data_dir - -let default_rpc_addr = "127.0.0.1" - -let default_rpc_port = 8932 - -let default_reconnection_delay = 2.0 (* seconds *) - -let default_dal_node_addr = "127.0.0.1" - -let default_dal_node_port = 10732 - -let tez t = Tez.of_mutez_exn Int64.(mul (of_int t) 1_000_000L) - -let default_minimal_fees = Mempool.default_minimal_fees - -let default_minimal_nanotez_per_gas_unit = - Mempool.default_minimal_nanotez_per_gas_unit - -let default_minimal_nanotez_per_byte = Mempool.default_minimal_nanotez_per_byte - -let default_force_low_fee = false - -let default_fee_cap = tez 1 - -let default_burn_cap = Tez.zero - -(* The below default fee and burn limits are computed by taking into account - the worst fee found in the tests for the rollup node. - - We take as base the cost of commitment cementation, which is 719 mutez in fees: - - Commitment publishing is 1.37 times more expensive. - - Message submission is 0.7 times more expensive, so cheaper but it depends on - the size of the message. - - For refutation games: - - Open is 1.55 times more expensive. - - Dissection move is 2.31 times more expensive. - - Proof move is 1.47 times more expensive but depends on the size of the proof. - - Timeout move is 1.34 times more expensive. - - We set a fee limit of 1 tz for cementation (instead of 719 mutez) which - should be plenty enough even if the gas price or gas consumption - increases. We adjust the other limits in proportion. -*) -let default_fee = function - | Cement -> tez 1 - | Publish -> tez 2 - | Add_messages -> - (* We keep this limit even though it depends on the size of the message - because the rollup node pays the fees for messages submitted by the - **users**. *) - tez 1 - | Timeout -> tez 2 - | Refute -> - (* Should be 3 based on comment above but we want to make sure we inject - refutation moves even if the proof is large. The stake is high (we can - lose the 10k deposit or we can get the reward). *) - tez 5 - -let default_burn = function - | Publish -> - (* The first commitment can store data. *) - tez 1 - | Add_messages -> tez 0 - | Cement -> tez 0 - | Timeout -> tez 0 - | Refute -> - (* A refutation move can store data, e.g. opening a game. *) - tez 1 - -let default_fee_parameter ?purpose () = - let fee_cap, burn_cap = - match purpose with - | None -> (default_fee_cap, default_burn_cap) - | Some purpose -> (default_fee purpose, default_burn purpose) - in - { - Injection.minimal_fees = default_minimal_fees; - minimal_nanotez_per_byte = default_minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit = default_minimal_nanotez_per_gas_unit; - force_low_fee = default_force_low_fee; - fee_cap; - burn_cap; - } - -let default_fee_parameters = - List.fold_left - (fun acc purpose -> - Operator_purpose_map.add purpose (default_fee_parameter ~purpose ()) acc) - Operator_purpose_map.empty - purposes - -let string_of_purpose = function - | Publish -> "publish" - | Add_messages -> "add_messages" - | Cement -> "cement" - | Timeout -> "timeout" - | Refute -> "refute" - -let purpose_of_string = function - | "publish" -> Some Publish - | "add_messages" -> Some Add_messages - | "cement" -> Some Cement - | "timeout" -> Some Timeout - | "refute" -> Some Refute - | _ -> None - -let purpose_of_string_exn s = - match purpose_of_string s with - | Some p -> p - | None -> invalid_arg ("purpose_of_string " ^ s) - -let add_fallbacks map fallbacks = - List.fold_left - (fun map (missing_purpose, fallback_purpose) -> - if Operator_purpose_map.mem missing_purpose map then - (* No missing purpose, don't fallback *) - map - else - match Operator_purpose_map.find fallback_purpose map with - | None -> - (* Nothing to fallback on *) - map - | Some operator -> Operator_purpose_map.add missing_purpose operator map) - map - fallbacks - -let make_purpose_map ~default bindings = - let map = Operator_purpose_map.of_seq @@ List.to_seq bindings in - let map = add_fallbacks map [(Timeout, Refute)] in - match default with - | None -> map - | Some default -> - List.fold_left - (fun map purpose -> - if Operator_purpose_map.mem purpose map then map - else Operator_purpose_map.add purpose default map) - map - purposes - -let operator_purpose_map_encoding encoding = - let open Data_encoding in - let schema = - let open Json_schema in - let v_schema p = Data_encoding.Json.schema (encoding p) in - let v_schema_r p = root (v_schema p) in - let kind = - Object - { - properties = - List.map - (fun purpose -> - (string_of_purpose purpose, v_schema_r purpose, false, None)) - purposes; - pattern_properties = []; - additional_properties = None; - min_properties = 0; - max_properties = None; - schema_dependencies = []; - property_dependencies = []; - } - in - update (element kind) (v_schema Publish (* Dummy for definitions *)) - in - conv - ~schema - (fun map -> - let fields = - Operator_purpose_map.bindings map - |> List.map (fun (p, v) -> - (string_of_purpose p, Data_encoding.Json.construct (encoding p) v)) - in - `O fields) - (function - | `O fields -> - List.map - (fun (p, v) -> - let purpose = purpose_of_string_exn p in - (purpose, Data_encoding.Json.destruct (encoding purpose) v)) - fields - |> List.to_seq |> Operator_purpose_map.of_seq - | _ -> assert false) - Data_encoding.Json.encoding - -let operators_encoding = - operator_purpose_map_encoding (fun _ -> Signature.Public_key_hash.encoding) - -let fee_parameter_encoding purpose = - let open Data_encoding in - conv - (fun { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } -> - ( minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap )) - (fun ( minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) -> - { - minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - }) - (obj6 - (dft - "minimal-fees" - ~description:"Exclude operations with lower fees" - Tez.encoding - default_minimal_fees) - (dft - "minimal-nanotez-per-byte" - ~description:"Exclude operations with lower fees per byte" - Plugin.Mempool.nanotez_enc - default_minimal_nanotez_per_byte) - (dft - "minimal-nanotez-per-gas-unit" - ~description:"Exclude operations with lower gas fees" - Plugin.Mempool.nanotez_enc - default_minimal_nanotez_per_gas_unit) - (dft - "force-low-fee" - ~description: - "Don't check that the fee is lower than the estimated default" - bool - default_force_low_fee) - (dft - "fee-cap" - ~description:"The fee cap" - Tez.encoding - (default_fee purpose)) - (dft - "burn-cap" - ~description:"The burn cap" - Tez.encoding - (default_burn purpose))) - -let fee_parameters_encoding = - operator_purpose_map_encoding fee_parameter_encoding - -let modes = [Observer; Batcher; Maintenance; Operator; Custom] - -let string_of_mode = function - | Observer -> "observer" - | Batcher -> "batcher" - | Maintenance -> "maintenance" - | Operator -> "operator" - | Custom -> "custom" - -let mode_of_string = function - | "observer" -> Ok Observer - | "batcher" -> Ok Batcher - | "maintenance" -> Ok Maintenance - | "operator" -> Ok Operator - | "custom" -> Ok Custom - | _ -> Error [Exn (Failure "Invalid mode")] - -let description_of_mode = function - | Observer -> "Only follows the chain, reconstructs and interprets inboxes" - | Batcher -> - "Accepts transactions in its queue and batches them on the L1 (TODO)" - | Maintenance -> - "Follows the chain and publishes commitments, cement and refute" - | Operator -> "Equivalent to maintenance + batcher" - | Custom -> - "In this mode, only operations that have a corresponding operator/signer \ - are injected" - -let mode_encoding = - Data_encoding.string_enum - [ - ("observer", Observer); - ("batcher", Batcher); - ("maintenance", Maintenance); - ("operator", Operator); - ("custom", Custom); - ] - -let encoding : t Data_encoding.t = - let open Data_encoding in - conv - (fun { - data_dir; - sc_rollup_address; - sc_rollup_node_operators; - rpc_addr; - rpc_port; - reconnection_delay; - fee_parameters; - mode; - loser_mode; - dal_node_addr; - dal_node_port; - } -> - ( ( data_dir, - sc_rollup_address, - sc_rollup_node_operators, - rpc_addr, - rpc_port, - reconnection_delay, - fee_parameters, - mode, - loser_mode ), - (dal_node_addr, dal_node_port) )) - (fun ( ( data_dir, - sc_rollup_address, - sc_rollup_node_operators, - rpc_addr, - rpc_port, - reconnection_delay, - fee_parameters, - mode, - loser_mode ), - (dal_node_addr, dal_node_port) ) -> - { - data_dir; - sc_rollup_address; - sc_rollup_node_operators; - rpc_addr; - rpc_port; - reconnection_delay; - fee_parameters; - mode; - loser_mode; - dal_node_addr; - dal_node_port; - }) - (merge_objs - (obj9 - (dft - "data-dir" - ~description:"Location of the data dir" - string - default_data_dir) - (req - "sc-rollup-address" - ~description:"Smart contract rollup address" - Protocol.Alpha_context.Sc_rollup.Address.encoding) - (req - "sc-rollup-node-operator" - ~description: - "Operators that sign operations of the smart contract rollup, \ - by purpose" - operators_encoding) - (dft "rpc-addr" ~description:"RPC address" string default_rpc_addr) - (dft "rpc-port" ~description:"RPC port" int16 default_rpc_port) - (dft - "reconnection_delay" - ~description: - "The reconnection (to the tezos node) delay in seconds" - float - default_reconnection_delay) - (dft - "fee-parameters" - ~description: - "The fee parameters for each purpose used when injecting \ - operations in L1" - fee_parameters_encoding - default_fee_parameters) - (req - ~description:"The mode for this rollup node" - "mode" - mode_encoding) - (dft - "loser-mode" - ~description: - "If enabled, the rollup node will issue wrong commitments (for \ - test only!)" - Loser_mode.encoding - Loser_mode.no_failures)) - (obj2 - (dft "DAL node address" string default_dal_node_addr) - (dft "DAL node port" int16 default_dal_node_port))) - -let check_mode config = - let open Result_syntax in - let check_purposes purposes = - let missing_operators = - List.filter - (fun p -> - not (Operator_purpose_map.mem p config.sc_rollup_node_operators)) - purposes - in - if missing_operators <> [] then - let mode = string_of_mode config.mode in - let missing_operators = List.map string_of_purpose missing_operators in - tzfail - (Sc_rollup_node_errors.Missing_mode_operators {mode; missing_operators}) - else return_unit - in - let narrow_purposes purposes = - let+ () = check_purposes purposes in - let sc_rollup_node_operators = - Operator_purpose_map.filter - (fun op_purpose _ -> List.mem ~equal:Stdlib.( = ) op_purpose purposes) - config.sc_rollup_node_operators - in - {config with sc_rollup_node_operators} - in - match config.mode with - | Observer -> narrow_purposes [] - | Batcher -> narrow_purposes [Add_messages] - | Maintenance -> narrow_purposes [Publish; Cement; Refute] - | Operator -> narrow_purposes [Publish; Cement; Add_messages; Refute] - | Custom -> return config - -let loser_warning_message config = - if config.loser_mode <> Loser_mode.no_failures then - Format.printf - {| -************ WARNING ************* -This rollup node is in loser mode. -This should be used for test only! -************ WARNING ************* -|} - -let save config = - loser_warning_message config ; - let open Lwt_syntax in - let json = Data_encoding.Json.construct encoding config in - let* () = Lwt_utils_unix.create_dir config.data_dir in - Lwt_utils_unix.Json.write_file (filename config) json - -let load ~data_dir = - let open Lwt_result_syntax in - let+ json = Lwt_utils_unix.Json.read_file (relative_filename data_dir) in - let config = Data_encoding.Json.destruct encoding json in - loser_warning_message config ; - config diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/configuration.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/configuration.mli deleted file mode 100644 index 8560affc08a29fe77972f7ae65a6b07d103300ff..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/configuration.mli +++ /dev/null @@ -1,136 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* Copyright (c) 2022 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. *) -(* *) -(*****************************************************************************) - -(** Mode for the rollup node *) -type mode = - | Observer (** Only follows the chain and reconstructs inboxes *) - | Batcher (** Accept transactions in its queue and batches them on the L1 *) - | Maintenance (** Follows the chain and publishes commitments *) - | Operator (** Equivalent to maintenance + batcher *) - | Custom - (** This mode allows to tweak which operations are injected by selecting - the signers *) - -(** Purposes for operators, indicating the kind of operations that they sign. *) -type purpose = Publish | Add_messages | Cement | Timeout | Refute - -module Operator_purpose_map : Map.S with type key = purpose - -type operators = Signature.Public_key_hash.t Operator_purpose_map.t - -type fee_parameters = Injection.fee_parameter Operator_purpose_map.t - -type t = { - data_dir : string; - sc_rollup_address : Protocol.Alpha_context.Sc_rollup.t; - sc_rollup_node_operators : operators; - rpc_addr : string; - rpc_port : int; - reconnection_delay : float; - fee_parameters : fee_parameters; - mode : mode; - loser_mode : Loser_mode.t; - (*DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/3718 - Decide whether we want to handle connections to multiple - Dal nodes for different slot indexes. - *) - dal_node_addr : string; - dal_node_port : int; -} - -(** [make_purpose_map ~default purposes] constructs a purpose map from a list of - bindings [purposes], with a potential [default] value. *) -val make_purpose_map : - default:'a option -> (purpose * 'a) trace -> 'a Operator_purpose_map.t - -(** [purpose_of_string s] parses a purpose from the given string [s]. *) -val purpose_of_string : string -> purpose option - -(** [string_of_purpose p] returns a string representation of purpose [p]. *) -val string_of_purpose : purpose -> string - -(** List of possible purposes for operator specialization. *) -val purposes : purpose list - -(** [default_data_dir] is the default value for [data_dir]. *) -val default_data_dir : string - -(** [default_storage_dir] returns the default value of the storage dir - given a [data_dir]. *) -val default_storage_dir : string -> string - -(** [default_context_dir] returns the default value of the directory - for persisting the context given a [data_dir]. *) -val default_context_dir : string -> string - -(** [default_rpc_addr] is the default value for [rpc_addr]. *) -val default_rpc_addr : string - -(** [default_rpc_port] is the default value for [rpc_port]. *) -val default_rpc_port : int - -(** [default_reconnection_delay] is the default value for [reconnection_delay]. *) -val default_reconnection_delay : float - -(** [default_fee_parameter ?purpose ()] is the default fee parameter to inject - operation on L1. If [purpose] is provided, it returns the default fee - parameter for the specific purpose. *) -val default_fee_parameter : ?purpose:purpose -> unit -> Injection.fee_parameter - -(** [default_fee_parameters] is the default fee parameters configuration build - with {!default_fee_parameter} for all purposes. *) -val default_fee_parameters : fee_parameters - -(** [default_dal_node_addr] is the default value for [dal_node_addr]. *) -val default_dal_node_addr : string - -(** [default_dal_node_port] is the default value for [dal_node_port]. *) -val default_dal_node_port : int - -(** This is the list of available modes. *) -val modes : mode list - -(** [string_of_mode mode] returns a string representation of the mode [mode]. *) -val string_of_mode : mode -> string - -(** [mode_of_string s] returns the mode represented by string [s] if it exists. *) -val mode_of_string : string -> mode tzresult - -(** [description_of_mode m] returns a textual description of the mode [m]. *) -val description_of_mode : mode -> string - -(** [filename configuration] returns the [configuration] filename. *) -val filename : t -> string - -(** [check_mode config] ensures the operators correspond to the chosen mode and - removes the extra ones. *) -val check_mode : t -> t tzresult - -(** [save configuration] overwrites [configuration] file. *) -val save : t -> unit tzresult Lwt.t - -(** [load ~data_dir] loads a configuration stored in [data_dir]. *) -val load : data_dir:string -> t tzresult Lwt.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/context.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/context.ml deleted file mode 100644 index 74aa8c0c991031b689a856ebf5ccc1747d0eed14..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/context.ml +++ /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 -module Maker = Irmin_pack_unix.Maker (Tezos_context_encoding.Context.Conf) - -module IStore = struct - include Maker.Make (Tezos_context_encoding.Context.Schema) - module Schema = Tezos_context_encoding.Context.Schema -end - -module IStoreTree = - Tezos_context_helpers.Context.Make_tree - (Tezos_context_encoding.Context.Conf) - (IStore) - -type tree = IStore.tree - -type index = {path : string; repo : IStore.Repo.t} - -type t = {index : index; tree : tree} - -type commit = IStore.commit - -type hash = IStore.hash - -type path = string list - -let hash_encoding = - let open Data_encoding in - conv - (fun h -> IStore.Hash.to_raw_string h |> Bytes.unsafe_of_string) - (fun b -> Bytes.unsafe_to_string b |> IStore.Hash.unsafe_of_raw_string) - (Fixed.bytes IStore.Hash.hash_size) - -let hash_to_raw_string = IStore.Hash.to_raw_string - -let pp_hash fmt h = - IStore.Hash.to_raw_string h - |> Hex.of_string |> Hex.show |> Format.pp_print_string fmt - -let load configuration = - let open Lwt_syntax in - let open Configuration in - let path = default_context_dir configuration.data_dir in - let+ repo = IStore.Repo.v (Irmin_pack.config path) in - {path; repo} - -let close ctxt = IStore.Repo.close ctxt.repo - -let raw_commit ?(message = "") index tree = - let info = IStore.Info.v ~author:"Tezos" 0L ~message in - IStore.Commit.v index.repo ~info ~parents:[] tree - -let commit ?message ctxt = - let open Lwt_syntax in - let+ commit = raw_commit ?message ctxt.index ctxt.tree in - IStore.Commit.hash commit - -let checkout index key = - let open Lwt_syntax in - let* o = IStore.Commit.of_hash index.repo key in - match o with - | None -> return_none - | Some commit -> - let tree = IStore.Commit.tree commit in - return_some {index; tree} - -let empty index = {index; tree = IStore.Tree.empty ()} - -let is_empty ctxt = IStore.Tree.is_empty ctxt.tree - -module Proof (Hash : sig - type t - - val of_context_hash : Context_hash.t -> t -end) (Proof_encoding : sig - val proof_encoding : - Environment.Context.Proof.tree Environment.Context.Proof.t Data_encoding.t -end) = -struct - module IStoreProof = - Tezos_context_helpers.Context.Make_proof - (IStore) - (Tezos_context_encoding.Context.Conf) - - module Tree = struct - include IStoreTree - - type nonrec t = index - - type tree = IStore.tree - - type key = path - - type value = bytes - end - - type tree = Tree.tree - - type proof = IStoreProof.Proof.tree IStoreProof.Proof.t - - let hash_tree tree = Hash.of_context_hash (Tree.hash tree) - - let proof_encoding = Proof_encoding.proof_encoding - - let proof_before proof = - let (`Value hash | `Node hash) = proof.IStoreProof.Proof.before in - Hash.of_context_hash hash - - let proof_after proof = - let (`Value hash | `Node hash) = proof.IStoreProof.Proof.after in - Hash.of_context_hash hash - - let produce_proof index tree step = - let open Lwt_syntax in - (* Committing the context is required by Irmin to produce valid proofs. *) - let* _commit_key = raw_commit index tree in - match Tree.kinded_key tree with - | Some k -> - let* p = IStoreProof.produce_tree_proof index.repo k step in - return (Some p) - | None -> return None - - let verify_proof proof step = - (* The rollup node is not supposed to verify proof. We keep - this part in case this changes in the future. *) - let open Lwt_syntax in - let* result = IStoreProof.verify_tree_proof proof step in - match result with - | Ok v -> return (Some v) - | Error _ -> - (* We skip the error analysis here since proof verification is not a - job for the rollup node. *) - return None -end - -(** Aggregated collection of messages from the L1 inbox *) -module MessageTrees = struct - type value = tree - - let key = ["message_tree"] - - let find ctxt = IStore.Tree.find_tree ctxt.tree key - - let set ctxt tree = - let open Lwt_syntax in - let* tree = IStore.Tree.add_tree ctxt.tree key tree in - let ctxt = {ctxt with tree} in - return ctxt -end - -module Inbox = struct - include Sc_rollup.Inbox - module Message = Sc_rollup.Inbox_message - - include Sc_rollup.Inbox.Make_hashing_scheme (struct - include - Proof - (Hash) - (struct - let proof_encoding = - Tezos_context_merkle_proof_encoding.Merkle_proof_encoding.V1.Tree32 - .tree_proof_encoding - end) - - type t = index - - let commit_tree index _key tree = - let open Lwt_syntax in - let info () = IStore.Info.v ~author:"Tezos" 0L ~message:"" in - let* (_ : IStore.commit) = - IStore.Commit.v index.repo ~info:(info ()) ~parents:[] tree - in - return () - - let from_inbox_hash inbox_hash = - let ctxt_hash = Hash.to_context_hash inbox_hash in - let store_hash = - IStore.Hash.unsafe_of_raw_string (Context_hash.to_string ctxt_hash) - in - `Node store_hash - - let lookup_tree index hash = - IStore.Tree.of_hash index.repo (from_inbox_hash hash) - end) -end - -(** State of the PVM that this rollup node deals with. *) -module PVMState = struct - type value = tree - - let key = ["pvm_state"] - - let find ctxt = IStore.Tree.find_tree ctxt.tree key - - let lookup tree path = IStore.Tree.find tree path - - let set ctxt state = - let open Lwt_syntax in - let+ tree = IStore.Tree.add_tree ctxt.tree key state in - {ctxt with tree} -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/context.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/context.mli deleted file mode 100644 index 5e9aa163dd268185f39807fe0860430f8309a285..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/context.mli +++ /dev/null @@ -1,181 +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 - -(** The type of indexed repository for contexts *) -type index - -(** The type of trees stored in the context, i.e. the actual data. *) -type tree - -(** The type of context with its content *) -type t - -(** A context hash is the hash produced when the data of the context is - committed to disk, i.e. the {!commit} hash. *) -type hash - -(** The type of commits for the context. *) -type commit - -(** [hash_encoding] is the encoding for context hashes, of type {!hash}. *) -val hash_encoding : hash Data_encoding.t - -(** [hash_to_raw_string h] is the raw string representation for the hash [h]. *) -val hash_to_raw_string : hash -> string - -(** [pp_hash fmt h] prints the hash [h] in hexadecimal notation on the formatter - [fmt]. *) -val pp_hash : Format.formatter -> hash -> unit - -(** [load config] initializes from disk a context using the [data_dir] - information contained in the configuration [config]. *) -val load : Configuration.t -> index Lwt.t - -(** [close ctxt] closes the context index [ctxt]. *) -val close : index -> unit Lwt.t - -(** [raw_commit ?message ctxt tree] commits the [tree] in the context repository - [ctxt] on disk, and return the commit. *) -val raw_commit : ?message:string -> index -> tree -> commit Lwt.t - -(** [commit ?message context] commits content of the context [context] on disk, - and return the commit hash. *) -val commit : ?message:string -> t -> hash Lwt.t - -(** [checkout ctxt hash] checkouts the content that corresponds to the commit - hash [hash] in the repository [ctxt] and returns the corresponding - context. If there is no commit that corresponds to [hash], it returns - [None]. *) -val checkout : index -> hash -> t option Lwt.t - -(** [empty ctxt] is the context with an empty content for the repository [ctxt]. *) -val empty : index -> t - -(** [is_empty context] returns [true] iff the context content of [context] is - empty. *) -val is_empty : t -> bool - -(** Module for generating and verifying proofs for a context *) -module Proof (Hash : sig - type t - - val of_context_hash : Context_hash.t -> t -end) (Proof_encoding : sig - val proof_encoding : - Environment.Context.Proof.tree Environment.Context.Proof.t Data_encoding.t -end) : sig - module Tree : - Tezos_context_sigs.Context.TREE - with type key = string list - and type value = bytes - and type t = index - and type tree = tree - - type tree = Tree.tree - - (** See {!Sc_rollup_PVM_sem.proof} *) - type proof - - val hash_tree : tree -> Hash.t - - (** See {!Sc_rollup_PVM_sem.proof_encoding} *) - val proof_encoding : proof Data_encoding.t - - (** [proof_before proof] is the hash of the state before the step that - generated [rpoof]. *) - val proof_before : proof -> Hash.t - - (** [proof_after proof] is the hash of the state after the step that generated - [rpoof]. *) - val proof_after : proof -> Hash.t - - (** [produce_proof ctxt tree f] produces and returns a proof for the execution - of [f] on the state [tree]. *) - val produce_proof : - index -> tree -> (tree -> (tree * 'a) Lwt.t) -> (proof * 'a) option Lwt.t - - (** [verify_proof proof f] verifies that [f] produces the proof [proof] and - returns the resulting [tree], or [None] if the proof cannot be - verified. *) - val verify_proof : - proof -> (tree -> (tree * 'a) Lwt.t) -> (tree * 'a) option Lwt.t -end - -(** Aggregated collection of messages from the L1 inbox. *) -module MessageTrees : sig - (** The value of a messages tree *) - type value - - (** [find context] returns the messages tree stored in the [context], if any. *) - val find : t -> value option Lwt.t - - (** [set context msg_tree] saves the messages tree [msg_tree] in the context - and returns the updated context. Note: [set] does not perform any write on - disk, this information must be committed using {!commit}. *) - val set : t -> value -> t Lwt.t -end - -(** L1 inboxes representation in the rollup node. This is a version of the - protocols inboxes specialized to message trees ({!MessageTrees}) and which - can produce proofs for inboxes stored in the context. *) -module Inbox : sig - type t = Sc_rollup.Inbox.t - - module Message : module type of Sc_rollup.Inbox_message - - val pp : Format.formatter -> t -> unit - - val encoding : t Data_encoding.t - - val inbox_level : t -> Raw_level.t - - type history_proof = Sc_rollup.Inbox.history_proof - - include - Sc_rollup.Inbox.Merkelized_operations - with type tree = MessageTrees.value - and type inbox_context = index -end - -(** State of the PVM that this rollup node deals with *) -module PVMState : sig - (** The value of a PVM state *) - type value = tree - - (** [find context] returns the PVM state stored in the [context], if any. *) - val find : t -> value option Lwt.t - - (** [lookup state path] returns the data stored for the path [path] in the PVM - state [state]. *) - val lookup : value -> string list -> bytes option Lwt.t - - (** [set context state] saves the PVM state [state] in the context and returns - the updated context. Note: [set] does not perform any write on disk, this - information must be committed using {!commit}. *) - val set : t -> value -> t Lwt.t -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/daemon.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/daemon.ml deleted file mode 100644 index 0391b2ccd844528d0ee0ab8afb996f779f1afc38..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/daemon.ml +++ /dev/null @@ -1,500 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 head_state = {head : Layer1.head; finalized : bool; seen_before : bool} - -let emit_head_processing_event - {head = Head {hash; level}; finalized; seen_before} = - Daemon_event.head_processing hash level finalized seen_before - -let emit_heads_not_processed_event head_states = - Lwt_list.iter_s - (fun {head = Head {hash; level}; _} -> - Daemon_event.not_finalized_head hash level) - head_states - -let categorise_heads (node_ctxt : Node_context.t) old_heads new_heads = - (* For each head, determine if it has already been seen before and if it has - been finalized, using the block finality time (for Tenderbake, this - is 2). - *) - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2868 - Handle protocols with non-deterministic finality. *) - let all_heads = old_heads @ new_heads in - let number_of_temporary_heads = - min node_ctxt.block_finality_time (List.length all_heads) - in - - let number_of_new_heads = List.length new_heads in - - let head_states, _, _ = - List.fold_right - (fun head (heads, n, m) -> - ({head; finalized = n <= 0; seen_before = m <= 0} :: heads, n - 1, m - 1)) - all_heads - ([], number_of_temporary_heads, number_of_new_heads) - in - head_states - -module Make (PVM : Pvm.S) = struct - module Components = Components.Make (PVM) - open Protocol - open Alpha_context - open Apply_results - - (** Process an L1 SCORU operation (for the node's rollup) which is included - for the first time. {b Note}: this function does not process inboxes for - the rollup, which is done instead by {!Inbox.process_head}. *) - let process_included_l1_operation (type kind) (node_ctxt : Node_context.t) - head ~source:_ (operation : kind manager_operation) - (result : kind successful_manager_operation_result) = - let open Lwt_result_syntax in - match (operation, result) with - | ( Sc_rollup_publish {commitment; _}, - Sc_rollup_publish_result {published_at_level; _} ) -> - (* Published commitment --------------------------------------------- *) - let commitment_hash = - Sc_rollup.Commitment.hash_uncarbonated commitment - in - let*! () = - Store.Commitments_published_at_level.add - node_ctxt.store - commitment_hash - published_at_level - in - return_unit - | Sc_rollup_cement {commitment; _}, Sc_rollup_cement_result {inbox_level; _} - -> - (* Cemented commitment ---------------------------------------------- *) - let*! () = - Store.Last_cemented_commitment_level.set node_ctxt.store inbox_level - in - let*! () = - Store.Last_cemented_commitment_hash.set node_ctxt.store commitment - in - return_unit - | ( Sc_rollup_refute _, - Sc_rollup_refute_result - {game_status = Ended (Loser {reason; loser}); balance_updates; _} ) - when Node_context.is_operator node_ctxt loser -> - let*? slashed_amount = - List.fold_left_e - (fun slashed -> function - | ( Receipt.Sc_rollup_refutation_punishments, - Receipt.Credited amount, - _ ) -> - Environment.wrap_tzresult Tez.(slashed +? amount) - | _ -> Ok slashed) - Tez.zero - balance_updates - in - tzfail (Sc_rollup_node_errors.Lost_game (loser, reason, slashed_amount)) - | Dal_publish_slot_header {slot}, Dal_publish_slot_header_result _ -> - let {Dal.Slot.id = {index; _}; _} = slot in - (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/3510 - We store slot headers for all slots. In practice, - it would be convenient to store only information about - headers of slots to which the rollup node is subscribed to. - We do not have the information about DAL slots subscribed to - at this time. *) - let*! () = - Store.Dal_slots.add - node_ctxt.store - ~primary_key:head - ~secondary_key:index - slot - in - return_unit - | _, _ -> - (* Other manager operations *) - return_unit - - (** Process an L1 SCORU operation (for the node's rollup) which is finalized - for the first time. *) - let process_finalized_l1_operation (type kind) _node_ctxt _head ~source:_ - (_operation : kind manager_operation) - (_result : kind successful_manager_operation_result) = - return_unit - - let process_l1_operation (type kind) ~finalized node_ctxt head ~source - (operation : kind manager_operation) - (result : kind Apply_results.manager_operation_result) = - let open Lwt_result_syntax in - let is_for_my_rollup : type kind. kind manager_operation -> bool = function - | Sc_rollup_add_messages {rollup; _} - | Sc_rollup_cement {rollup; _} - | Sc_rollup_publish {rollup; _} - | Sc_rollup_refute {rollup; _} - | Sc_rollup_timeout {rollup; _} - | Sc_rollup_execute_outbox_message {rollup; _} - | Sc_rollup_recover_bond {sc_rollup = rollup} - | Sc_rollup_dal_slot_subscribe {rollup; _} -> - Sc_rollup.Address.(rollup = node_ctxt.Node_context.rollup_address) - | Dal_publish_slot_header _ -> true - | Reveal _ | Transaction _ | Origination _ | Delegation _ - | Update_consensus_key _ | Register_global_constant _ - | Set_deposits_limit _ | Increase_paid_storage _ | Tx_rollup_origination - | Tx_rollup_submit_batch _ | Tx_rollup_commit _ | Tx_rollup_return_bond _ - | Tx_rollup_finalize_commitment _ | Tx_rollup_remove_commitment _ - | Tx_rollup_rejection _ | Tx_rollup_dispatch_tickets _ | Transfer_ticket _ - | Sc_rollup_originate _ | Zk_rollup_origination _ | Zk_rollup_publish _ -> - false - in - if not (is_for_my_rollup operation) then return_unit - else - (* Only look at operations that are for the node's rollup *) - let*! () = Daemon_event.included_operation ~finalized operation result in - match result with - | Applied success_result -> - let process = - if finalized then process_finalized_l1_operation - else process_included_l1_operation - in - process node_ctxt head ~source operation success_result - | _ -> - (* No action for non successful operations *) - return_unit - - let process_l1_block_operations ~finalized node_ctxt (Layer1.Head {hash; _}) = - let open Lwt_result_syntax in - let* block = Layer1.fetch_tezos_block node_ctxt.Node_context.l1_ctxt hash in - let apply (type kind) accu ~source (operation : kind manager_operation) - result = - let open Lwt_result_syntax in - let* () = accu in - process_l1_operation ~finalized node_ctxt hash ~source operation result - in - let apply_internal (type kind) accu ~source:_ - (_operation : kind Apply_internal_results.internal_operation) - (_result : kind Apply_internal_results.internal_operation_result) = - accu - in - let* () = - Layer1_services.process_manager_operations - return_unit - block.operations - {apply; apply_internal} - in - return_unit - - let process_head configuration node_ctxt head_state = - let open Lwt_result_syntax in - let {finalized; seen_before; head} = head_state in - let* () = - let*! () = emit_head_processing_event head_state in - (* Avoid processing inbox again if it has been processed before for this head *) - if seen_before then - if finalized then process_l1_block_operations ~finalized node_ctxt head - else return_unit - else - let* ctxt = Inbox.process_head node_ctxt head in - let* () = Dal_slots_tracker.process_head node_ctxt head in - let* () = process_l1_block_operations ~finalized node_ctxt head in - (* Avoid storing and publishing commitments if the head is not final *) - (* Avoid triggering the pvm execution if this has been done before for this head *) - Components.Interpreter.process_head node_ctxt ctxt head - in - let* () = - when_ finalized @@ fun () -> - Components.Commitment.process_head node_ctxt head - in - (* Publishing a commitment when one is available does not depend on the state of - the current head. *) - let* () = Components.Commitment.publish_commitment node_ctxt in - let* () = - Components.Commitment.cement_commitment_if_possible node_ctxt head - in - let* () = - (* At each block, there may be some refutation related actions to - be performed. *) - when_ finalized @@ fun () -> - Components.Refutation_game.process head configuration node_ctxt - in - when_ finalized (fun () -> - let*! () = Layer1.mark_processed_head node_ctxt.store head in - return ()) - - let notify_injector {Node_context.l1_ctxt; store; _} chain_event = - let open Lwt_result_syntax in - let open Layer1 in - let hash = chain_event_head_hash chain_event in - let* head = fetch_tezos_block l1_ctxt hash in - let* reorg = get_tezos_reorg_for_new_head l1_ctxt store hash in - let*! () = Injector.new_tezos_head head reorg in - return_unit - - (* [on_layer_1_chain_event node_ctxt store chain_event] processes a - list of heads, coming either from a list of [old_heads] persisted in the - store, or from the current [chain_event]. [old_heads] is a list of heads - that have not been recognised as finalised by the rollup node. This list - has been set by the last iteration of [on_layer_1_chain_event] in - the {!daemonize} function, or it is the empty list if the rollup node is - executing [on_layer_1_chain_event] for the very first time. - These are heads included in - the branch currently tracked by the rollup node, and that - have only been partially processed, due to the rollup node not being able - to establish their finality. The function persists to disk the list of - heads from the current branch tracked by the rollup node, - whose finality cannot be established at the time the function is invoked. - Those heads will be processed again at the next iteration of - [on_layer_1_chain_event] in the [daemonize] function. If [chain_event] is - a rollback event, then the list of heads persisted to disk is reset to the - empty list, as the rollup node started tracking a new branch. - Because heads that still have not been processed as finalized are - persisted to disk, this function is robust against interruptions. - *) - let on_layer_1_chain_event configuration node_ctxt chain_event = - let open Lwt_result_syntax in - let*! old_heads = - Layer1.get_heads_not_finalized node_ctxt.Node_context.store - in - let open Layer1 in - let* () = - (* Get information about the last cemented commitment to determine the - commitment (if any) to publish next. We do this only once per - chain event to avoid spamming the layer1 node. *) - Components.Commitment.sync_last_cemented_commitment_hash_with_level - node_ctxt - in - let* () = notify_injector node_ctxt chain_event in - let* non_final_heads = - match chain_event with - | SameBranch {new_head; intermediate_heads} -> - let new_heads = intermediate_heads @ [new_head] in - let*! () = - Daemon_event.processing_heads_iteration old_heads new_heads - in - let head_states = categorise_heads node_ctxt old_heads new_heads in - let* () = - List.iter_es (process_head configuration node_ctxt) head_states - in - (* Return new_head to be processed as finalized head if the - next chain event is of type SameBranch. - *) - let non_final_head_states = - List.filter (fun head_state -> not head_state.finalized) head_states - in - let*! () = emit_heads_not_processed_event non_final_head_states in - let non_final_heads = - List.map (fun head_state -> head_state.head) non_final_head_states - in - return non_final_heads - | Rollback {new_head = Layer1.Head {level = new_level; _}} -> - (* The new_head of the rollback event corresponds to a head that - was previously finalized. Heads in `old_heads` that have a level - preceding or equal to `new_level` can now be considered final, - and will be processed as such. `new_level` can now be considered - as such. Heads in `old_heads` whose level is greater than - `new_level` can be safely discarded. - *) - let final_heads, _non_final_heads = - List.partition - (fun head -> - let (Layer1.Head {level; _}) = head in - level <= new_level) - old_heads - in - let+ () = - List.iter_es - (fun head -> - process_head - configuration - node_ctxt - {head; finalized = true; seen_before = true}) - final_heads - in - [] - in - let*! () = Layer1.set_heads_not_finalized node_ctxt.store non_final_heads in - let*! () = Layer1.processed chain_event in - let*! () = Injector.inject () in - return_unit - - let is_connection_error trace = - TzTrace.fold - (fun yes error -> - yes - || - match error with - | Tezos_rpc_http.RPC_client_errors.( - Request_failed {error = Connection_failed _; _}) -> - true - | _ -> false) - false - trace - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2895 - Use Lwt_stream.fold_es once it is exposed. *) - let daemonize configuration (node_ctxt : Node_context.t) = - let open Lwt_result_syntax in - let rec loop (l1_ctxt : Layer1.t) = - let*! () = - Lwt_stream.iter_s - (fun event -> - let open Lwt_syntax in - let* res = on_layer_1_chain_event configuration node_ctxt event in - match res with - | Ok () -> return_unit - | Error trace when is_connection_error trace -> - Format.eprintf - "@[Connection error:@ %a@]@." - pp_print_trace - trace ; - l1_ctxt.stopper () ; - return_unit - | Error e -> - Format.eprintf "%a@.Exiting.@." pp_print_trace e ; - let* _ = Lwt_exit.exit_and_wait 1 in - return_unit) - l1_ctxt.events - in - let*! () = Event.connection_lost () in - let* l1_ctxt = - Layer1.reconnect configuration node_ctxt.l1_ctxt node_ctxt.store - in - loop l1_ctxt - in - protect @@ fun () -> Lwt.no_cancel @@ loop node_ctxt.l1_ctxt - - let install_finalizer {Node_context.l1_ctxt; store; _} rpc_server = - let open Lwt_syntax in - Lwt_exit.register_clean_up_callback ~loc:__LOC__ @@ fun exit_status -> - let message = l1_ctxt.cctxt#message in - let* () = message "Stopping L1 monitor@." in - l1_ctxt.stopper () ; - let* () = message "Shutting down L1@." in - let* () = Layer1.shutdown store in - let* () = message "Shutting down RPC server@." in - let* () = Components.RPC_server.shutdown rpc_server in - let* () = message "Closing store@." in - let* () = Store_utils.close store in - let* () = Event.shutdown_node exit_status in - Tezos_base_unix.Internal_event_unix.close () - - let check_initial_state_hash {Node_context.cctxt; rollup_address; context; _} - = - let open Lwt_result_syntax in - let* l1_reference_initial_state_hash = - RPC.Sc_rollup.initial_pvm_state_hash - cctxt - (cctxt#chain, cctxt#block) - rollup_address - in - let*! s = PVM.initial_state context in - let*! l2_initial_state_hash = PVM.state_hash s in - if - not - Sc_rollup.State_hash.( - l1_reference_initial_state_hash = l2_initial_state_hash) - then - let*! () = - Daemon_event.wrong_initial_pvm_state_hash - l2_initial_state_hash - l1_reference_initial_state_hash - in - Lwt_exit.exit_and_raise 1 - else return_unit - - let run node_ctxt configuration = - let open Lwt_result_syntax in - let* () = check_initial_state_hash node_ctxt in - let start () = - let* rpc_server = Components.RPC_server.start node_ctxt configuration in - let (_ : Lwt_exit.clean_up_callback_id) = - install_finalizer node_ctxt rpc_server - in - let*! () = Inbox.start () in - let*! () = Components.Commitment.start () in - let signers = - Configuration.Operator_purpose_map.bindings node_ctxt.operators - |> List.fold_left - (fun acc (purpose, operator) -> - let purposes = - match Signature.Public_key_hash.Map.find operator acc with - | None -> [purpose] - | Some ps -> purpose :: ps - in - Signature.Public_key_hash.Map.add operator purposes acc) - Signature.Public_key_hash.Map.empty - |> Signature.Public_key_hash.Map.bindings - |> List.map (fun (operator, purposes) -> - (operator, `Each_block, purposes)) - in - let* () = - Injector.init - node_ctxt.cctxt - node_ctxt - ~data_dir:configuration.data_dir - ~signers - in - - let*! () = - Event.node_is_ready - ~rpc_addr:configuration.rpc_addr - ~rpc_port:configuration.rpc_port - in - daemonize configuration node_ctxt - in - start () -end - -let run ~data_dir (cctxt : Protocol_client_context.full) = - let open Lwt_result_syntax in - Random.self_init () (* Initialize random state (for reconnection delays) *) ; - let*! () = Event.starting_node () in - let* configuration = Configuration.load ~data_dir in - let dal_cctxt = Dal_node_client.make_unix_cctxt configuration in - let open Configuration in - let* () = - (* Check that the operators are valid keys. *) - Operator_purpose_map.iter_es - (fun _purpose operator -> - let+ _pkh, _pk, _skh = Client_keys.get_key cctxt operator in - ()) - configuration.sc_rollup_node_operators - in - let*! store = - Store_utils.load Configuration.(default_storage_dir configuration.data_dir) - in - let*! context = Context.load configuration in - let* l1_ctxt, kind = Layer1.start configuration cctxt store in - let* node_ctxt = - Node_context.init - cctxt - dal_cctxt - ~data_dir - l1_ctxt - configuration.sc_rollup_address - kind - configuration.sc_rollup_node_operators - configuration.fee_parameters - ~loser_mode:configuration.loser_mode - store - context - in - let module Daemon = Make ((val Components.pvm_of_kind node_ctxt.kind)) in - Daemon.run node_ctxt configuration diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/daemon_event.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/daemon_event.ml deleted file mode 100644 index 60ee3cf208c39a9b88230b4c4165c83e4fa1258f..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/daemon_event.ml +++ /dev/null @@ -1,166 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; "daemon"] - - let head_processing = - declare_4 - ~section - ~name:"sc_rollup_daemon_process_head" - ~msg: - "Processing: head {hash} at level {level}: finalized? {finalized}, \ - partially processed? {seen_before}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) - ("finalized", Data_encoding.bool) - ("seen_before", Data_encoding.bool) - - let not_finalized_head = - declare_2 - ~section - ~name:"sc_rollup_daemon_not_finalized" - ~msg: - "The following head has only be partially processed - commitments have \ - not been computed: Head {hash} at level {level}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) - - let processing_heads_iteration = - declare_2 - ~section - ~name:"sc_rollup_daemon_processing_heads" - ~msg: - "A new iteration of process_heads has been triggered: processing heads \ - from level {from} to level {to}" - ~level:Notice - ("from", Data_encoding.int32) - ("to", Data_encoding.int32) - - let included_successful_operation = - declare_1 - ~section - ~name:"sc_rollup_daemon_included_successful_operation" - ~msg:"Operation {operation} was included as successful" - ~level:Debug - ("operation", L1_operation.encoding) - ~pp1:L1_operation.pp - - let included_failed_operation = - declare_3 - ~section - ~name:"sc_rollup_daemon_included_failed_operation" - ~msg:"Operation {operation} was included as {status} with error {error}" - ~level:Warning - ("operation", L1_operation.encoding) - ( "status", - Data_encoding.( - string_enum - [ - ("failed", `Failed); - ("backtracked", `Backtracked); - ("skipped", `Skipped); - ]) ) - ("error", Data_encoding.option Environment.Error_monad.trace_encoding) - ~pp1:L1_operation.pp - ~pp3: - (fun ppf -> function - | None -> Format.pp_print_string ppf "none" - | Some e -> Environment.Error_monad.pp_trace ppf e) - - let finalized_successful_operation = - declare_1 - ~section - ~name:"sc_rollup_daemon_finalized_successful_operation" - ~msg:"Operation {operation} was finalized" - ~level:Debug - ("operation", L1_operation.encoding) - ~pp1:L1_operation.pp - - let wrong_initial_pvm_state_hash = - declare_2 - ~section - ~name:"sc_rollup_daemon_incorrect_initial_pvm_state_hash" - ~msg: - "The initial state hash produced by the PVM {actual} is not consistent\n\ - \ with the expected hash {expected}" - ~level:Notice - ("actual", Sc_rollup.State_hash.encoding) - ("expected", Sc_rollup.State_hash.encoding) -end - -let head_processing hash level finalized seen_before = - Simple.(emit head_processing (hash, level, finalized, seen_before)) - -let not_finalized_head hash level = - Simple.(emit not_finalized_head (hash, level)) - -let processing_heads_iteration old_heads new_heads = - let maybe_level = Option.map (fun (Layer1.Head {level; _}) -> level) in - let from_level = - match maybe_level @@ List.hd old_heads with - | None -> maybe_level @@ List.hd new_heads - | Some level -> Some level - in - let to_level = - match maybe_level @@ List.last_opt new_heads with - | None -> maybe_level @@ List.hd old_heads - | Some level -> Some level - in - match (from_level, to_level) with - | Some from_level, Some to_level -> - Simple.(emit processing_heads_iteration (from_level, to_level)) - | _ -> Lwt.return_unit - -let included_operation (type kind) ~finalized - (operation : kind Protocol.Alpha_context.manager_operation) - (result : kind Protocol.Apply_results.manager_operation_result) = - let operation = L1_operation.make operation in - match result with - | Applied _ when finalized -> - Simple.(emit finalized_successful_operation) operation - | _ when finalized -> - (* No events for finalized non successful operations *) - Lwt.return_unit - | Applied _ -> Simple.(emit included_successful_operation) operation - | result -> - let status, errors = - match result with - | Applied _ -> assert false - | Failed (_, e) -> (`Failed, Some e) - | Backtracked (_, e) -> (`Backtracked, e) - | Skipped _ -> (`Skipped, None) - in - Simple.(emit included_failed_operation) (operation, status, errors) - -let wrong_initial_pvm_state_hash actual_hash expected_hash = - Simple.(emit wrong_initial_pvm_state_hash (actual_hash, expected_hash)) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/daemon_event.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/daemon_event.mli deleted file mode 100644 index a20912df7f22a3d013b59f08269984db968e8756..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/daemon_event.mli +++ /dev/null @@ -1,61 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 defines functions that emit the events used by the smart - contract rollup node daemon (see {!Daemon}). *) - -(** [head_processing hash level finalized seen_before] emits the event that the - block of the given [hash] and at the given [level] is being processed, and - whether it is [finalized] and has been [seen_before]. *) -val head_processing : Block_hash.t -> int32 -> bool -> bool -> unit Lwt.t - -(** [not_finalized_head hash level] emits the event that the block of the given - [hash] and at the given [level] is being processed but has not been - finalized yet by the layer 1 consensus algorithm. *) -val not_finalized_head : Block_hash.t -> int32 -> unit Lwt.t - -(** [processing_heads_iteration old_heads new_heads] emits the event that a new - iteration of processing the heads has been triggered, from the level of the - oldest head to the level of the most recent head between the [old_heads] and - the [new_heads]. *) -val processing_heads_iteration : - Layer1.head list -> Layer1.head list -> unit Lwt.t - -(** [included_operation ~finalized op result] emits an event that an operation - for the rollup was included in a block (or finalized). *) -val included_operation : - finalized:bool -> - 'kind Protocol.Alpha_context.manager_operation -> - 'kind Protocol.Apply_results.manager_operation_result -> - unit Lwt.t - -(** [wrong_initial_pvm_state_hash actual_hash expected_hash] emits the event - that the initial state hash of the PVM [actual_hash] does not agree with - [expected_hash]. *) -val wrong_initial_pvm_state_hash : - Sc_rollup.State_hash.t -> Sc_rollup.State_hash.t -> unit Lwt.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_node_client.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_node_client.ml deleted file mode 100644 index 7b3192e24f9fb35d76a72ae9ed407726cb72bfd2..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_node_client.ml +++ /dev/null @@ -1,57 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 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 Tezos_dal_node_services - -class type cctxt = - object - inherit RPC_context.generic - end - -class unix_cctxt ~rpc_config : cctxt = - object - inherit - Tezos_rpc_http_client_unix.RPC_client_unix.http_ctxt - rpc_config - (Tezos_rpc_http.Media_type.Command_line.of_command_line - rpc_config.media_type) - end - -let make_unix_cctxt {Configuration.dal_node_addr; dal_node_port; _} = - let endpoint = - Uri.of_string ("http://" ^ dal_node_addr ^ ":" ^ string_of_int dal_node_port) - in - let rpc_config = - {Tezos_rpc_http_client_unix.RPC_client_unix.default_config with endpoint} - in - new unix_cctxt ~rpc_config - -let call (cctxt : #cctxt) = cctxt#call_service - -let get_slot cctxt ?(trim_slot = false) header = - call cctxt (Services.slot ()) ((), header) trim_slot () - -let get_shard cctxt header shard_index = - call cctxt (Services.shard ()) (((), header), shard_index) () () diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_node_client.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_node_client.mli deleted file mode 100644 index 7a0e3dc8ff7a359e213b6e5114a665e6873d4fa9..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_node_client.mli +++ /dev/null @@ -1,50 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 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 Protocol -open Alpha_context -open Tezos_crypto_dal - -(** Instance of [Tezos_client_base.Client_context] that only handles IOs and - RPCs. Can be used for keys and RPCs related commands. *) -class type cctxt = - object - inherit RPC_context.generic - end - -(** Instance of [cctxt] for linux systems. Relies on - [Tezos_rpc_http_client_unix]. *) -class unix_cctxt : - rpc_config:Tezos_rpc_http_client_unix.RPC_client_unix.config -> cctxt - -(** [make_unix_client_context config] generates a cctxt from - the client configuration. *) -val make_unix_cctxt : Configuration.t -> cctxt - -val get_slot : - #cctxt -> ?trim_slot:bool -> Dal.Slot.Header.t -> string tzresult Lwt.t - -val get_shard : - #cctxt -> Dal.Slot.Header.t -> int -> Cryptobox.shard tzresult Lwt.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_slots_tracker.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_slots_tracker.ml deleted file mode 100644 index 3a0f24f88e1e646de0d4786983c7acd52478ea20..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_slots_tracker.ml +++ /dev/null @@ -1,299 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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) - -type error += Cannot_read_block_metadata of Block_hash.t - -let () = - register_error_kind - ~id:"sc_rollup.node.cannot_read_receipt_of_block" - ~title:"Cannot read receipt of block from L1" - ~description:"The receipt of a block could not be read." - ~pp:(fun ppf hash -> - Format.fprintf - ppf - "Could not read block receipt for block with hash %a." - Block_hash.pp - hash) - `Temporary - Data_encoding.(obj1 (req "hash" Block_hash.encoding)) - (function Cannot_read_block_metadata hash -> Some hash | _ -> None) - (fun hash -> Cannot_read_block_metadata hash) - -let get_slot_subscriptions cctxt head rollup = - let open Lwt_result_syntax in - let*? level = Environment.wrap_tzresult @@ Raw_level.of_int32 (snd head) in - Plugin.RPC.Sc_rollup.dal_slot_subscriptions - cctxt - (cctxt#chain, cctxt#block) - rollup - level - -(* [fetch_and_save_subscribed_slot_headers cctxt head rollup] fetches the slot - indices to which [rollup] is subscribed to at [head], and stores them. *) -let fetch_and_save_subscribed_slot_headers - Node_context.{cctxt; rollup_address; store; _} - Layer1.(Head {level; hash = head_hash}) = - let open Lwt_result_syntax in - let* res = get_slot_subscriptions cctxt (head_hash, level) rollup_address in - let*! () = Store.Dal_slot_subscriptions.add store head_hash res in - return_unit - -let rec predecessor_hash ~levels node_ctxt (Layer1.Head {hash; level} as head) = - let open Lwt_option_syntax in - let genesis_level = node_ctxt.Node_context.genesis_info.level in - if level < Raw_level.to_int32 genesis_level then fail - else if levels = 0 then return hash - else - let*! pred_hash = Layer1.predecessor node_ctxt.store head in - let pred_head = - Layer1.Head {hash = pred_hash; level = Int32.(pred level)} - in - predecessor_hash ~levels:(levels - 1) node_ctxt pred_head - -(* Intersect two sorted lists. *) -module Slot_set = Set.Make (Dal.Slot_index) - -let common_slot_indexes (l : Dal.Slot_index.t list) (r : Dal.Slot_index.t list) - = - let l_set = Slot_set.of_list l in - let r_set = Slot_set.of_list r in - Slot_set.elements @@ Slot_set.inter l_set r_set - -(** [confirmed_slots node_ctxt head] reads the slot indexes that have been - declared available from [head]'s block receipt, and returns the list of - confirmed slots to which the rollup is subscribed to, with the corresponding - slot header. *) -let confirmed_slots node_ctxt (Layer1.Head {hash; _} as head) = - (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/3722 - The case for protocol migrations when the lag constant has - been changed is tricky, especially if the lag is reduced. - Suppose that a slot header is published at the second last level of a - cycle, and the lag is 2. The block is expected to be confirmed at the - first level of the new cycle. However, if during the protocol migration - we reduce the lag to 1, then the slots header will never be confirmed. - *) - let open Lwt_result_syntax in - let lag = - node_ctxt.Node_context.protocol_constants.parametric.dal.endorsement_lag - in - (* we are downloading endorsemented for slots at level [level], so - we need to download the data at level [level - lag]. - Therefore, we need to check only the slots to which the rollup node - was subscribed to at level `level - lag` - *) - let*! published_slots_block_hash = - predecessor_hash ~levels:lag node_ctxt head - in - match published_slots_block_hash with - | None -> return [] - | Some published_block_hash -> - let* {metadata; _} = - Layer1.fetch_tezos_block node_ctxt.Node_context.l1_ctxt hash - in - let*? metadata = - Option.to_result - ~none:(TzTrace.make @@ Cannot_read_block_metadata hash) - metadata - in - (* `metadata.protocol_data.dal_slot_availability` is `None` if we are behind - the `Dal feature flag`: in this case we return an empty slot endorsement. - *) - let confirmed_slots = - Option.value - ~default:Dal.Endorsement.empty - metadata.protocol_data.dal_slot_availability - in - let*! subscribed_slots_indexes = - Store.Dal_slot_subscriptions.get node_ctxt.store published_block_hash - in - let*! published_slots_indexes = - Store.Dal_slots.list_secondary_keys - node_ctxt.store - ~primary_key:published_block_hash - in - (* The list of slot_indexes l and r are guaranteed to be sorted. - List l is sorted because the protocol computes it from a bitset, - scanning the values 1 by 1. - List r is sorted because of the internal logic of list_inner_keys. *) - let relevant_slots_indexes = - common_slot_indexes subscribed_slots_indexes published_slots_indexes - |> List.filter (Dal.Endorsement.is_available confirmed_slots) - in - let*! () = - List.iter_s - (fun s -> - Dal_slots_tracker_event.slot_has_been_confirmed - s - published_block_hash - hash) - relevant_slots_indexes - in - let*! confirmed_slot_indexes_with_header = - List.map_p - (fun slot_index -> - Store.Dal_slots.get - node_ctxt.store - ~primary_key:published_block_hash - ~secondary_key:slot_index) - relevant_slots_indexes - in - - return confirmed_slot_indexes_with_header - -let save_confirmed_slot_headers node_ctxt hash slots_to_save = - List.iter_s - (fun (Dal.Slot.{id = {index; _}; _} as slot) -> - Store.Dal_confirmed_slots.add - node_ctxt.Node_context.store - ~primary_key:hash - ~secondary_key:index - slot) - slots_to_save - >|= ok - -module Confirmed_slots_history = struct - let read_slots_history_from_l1 {Node_context.l1_ctxt = {cctxt; _}; _} block = - let open Lwt_result_syntax in - (* We return the empty Slots_history if DAL is not enabled. *) - let* slots_list_opt = - RPC.Dal.dal_confirmed_slots_history cctxt (cctxt#chain, `Hash (block, 0)) - in - return @@ Option.value slots_list_opt ~default:Dal.Slots_history.genesis - - let slots_history_of_hash node_ctxt block_hash = - let open Lwt_result_syntax in - let open Node_context in - let*! confirmed_slots_history_opt = - Store.Dal_confirmed_slots_history.find node_ctxt.store block_hash - in - match confirmed_slots_history_opt with - | Some confirmed_dal_slots -> return confirmed_dal_slots - | None -> - let*! block_level = Layer1.level_of_hash node_ctxt.store block_hash in - let block_level = Raw_level.of_int32_exn block_level in - if Raw_level.(block_level <= node_ctxt.genesis_info.level) then - (* We won't find "dal slots history" for blocks before the - rollup origination level in the node's store. In this case, we get - the value of the skip list form L1 in case DAL is enabled, or the - genesis DAL skip list otherwise. *) - read_slots_history_from_l1 node_ctxt block_hash - else - (* We won't find "dal slots history" for blocks after the rollup - origination level. This should not happen in normal circumstances. *) - failwith - "The confirmed DAL slots history for block hash %a (level = %a) is \ - missing." - Block_hash.pp - block_hash - Raw_level.pp - block_level - - let slots_history_cache_of_hash node_ctxt block_hash = - let open Lwt_result_syntax in - let open Node_context in - let*! confirmed_slots_history_cache_opt = - Store.Dal_confirmed_slots_histories.find node_ctxt.store block_hash - in - match confirmed_slots_history_cache_opt with - | Some cache -> return cache - | None -> - let*! block_level = Layer1.level_of_hash node_ctxt.store block_hash in - let block_level = Raw_level.of_int32_exn block_level in - if Raw_level.(block_level <= node_ctxt.genesis_info.level) then - (* We won't find "dal slots history cache" for blocks before the - rollup origination level. In this case, we initialize with the - empty cache. *) - let num_slots = - node_ctxt.Node_context.protocol_constants.parametric.dal - .number_of_slots - in - (* FIXME/DAL: https://gitlab.com/tezos/tezos/-/issues/3788 - Put an accurate value for capacity. The value - `num_slots * 60000` below is chosen based on: - - The number of remembered L1 inboxes in their corresponding - cache (60000), - - The (max) number of slots (num_slots) that could be attested - per L1 block, - - The way the Slots_history.t skip list is implemented (one slot - per cell). *) - return - @@ Dal.Slots_history.History_cache.empty - ~capacity:(Int64.of_int @@ (num_slots * 60000)) - else - (* We won't find "dal slots history cache" for blocks after the rollup - origination level. This should not happen in normal circumstances. *) - failwith - "The confirmed DAL slots history cache for block hash %a (level = \ - %a) is missing." - Block_hash.pp - block_hash - Raw_level.pp - block_level - - let update (Node_context.{store; _} as node_ctxt) - Layer1.(Head {hash = head_hash; _} as head) slots_to_save = - let open Lwt_result_syntax in - let slots_to_save = - let open Dal in - List.fast_sort - (fun Slot.{id = {index = a; _}; _} {id = {index = b; _}; _} -> - Slot_index.compare a b) - slots_to_save - in - let*! pred = Layer1.predecessor store head in - let* slots_history = slots_history_of_hash node_ctxt pred in - let* slots_cache = slots_history_cache_of_hash node_ctxt pred in - let*? slots_history, slots_cache = - Dal.Slots_history.add_confirmed_slots - slots_history - slots_cache - slots_to_save - |> Environment.wrap_tzresult - in - (* The value of [slots_history] computed here is supposed to be equal to the - one computed stored for block [head_hash] on L1, we basically re-do the - computation here because we need to build/maintain the [slots_cache] - bounded cache in case we need it for refutation game. *) - (* TODO/DAL: https://gitlab.com/tezos/tezos/-/issues/3856 - Attempt to improve this process. *) - let*! () = - Store.Dal_confirmed_slots_history.add store head_hash slots_history - in - let*! () = - Store.Dal_confirmed_slots_histories.add store head_hash slots_cache - in - return () -end - -let process_head node_ctxt (Layer1.Head {hash = head_hash; _} as head) = - let open Lwt_result_syntax in - let* () = fetch_and_save_subscribed_slot_headers node_ctxt head in - let* slots_to_save = confirmed_slots node_ctxt head in - let* () = save_confirmed_slot_headers node_ctxt head_hash slots_to_save in - Confirmed_slots_history.update node_ctxt head slots_to_save diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_slots_tracker.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_slots_tracker.mli deleted file mode 100644 index 8849542988c5931beab8a67c7d224d470658f583..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_slots_tracker.mli +++ /dev/null @@ -1,46 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 rollup node keeps the list of dal slots to which the rollup is - subscribed to for each block it needs to process. This is to determine - whether the inbox for a given block will need to be retrieved from the - block operations, or from the data availability layer after lag levels - have passed and the slot for the block has been declared available. - - The state of subscribed slots per block is persistent. -*) - -type error += Cannot_read_block_metadata of Block_hash.t - -(** [process_head node_ctxt head] performs the following operations: - {ul - {li it fetches the slot indices to which the rollup is subscribed to, - and stores them in [Store.Dal_slot_subbscriptions] } - {li it reads the endorsements for headers published endorsement_lag - levels preceding [head] from the block metadata, determines which - ones the rollup node will download, and stores the results in - [Store.Dal_confirmed_slots].} - } *) -val process_head : Node_context.t -> Layer1.head -> unit tzresult Lwt.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_slots_tracker_event.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_slots_tracker_event.ml deleted file mode 100644 index c06c8afd1309db85b5842625df9d8dec0b4c021b..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dal_slots_tracker_event.ml +++ /dev/null @@ -1,50 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; "dal_slots_tracker"] - - let slot_has_been_confirmed = - declare_3 - ~section - ~name:"dal_confirmed_slot" - ~msg: - "Slot header for index {slot_index} was published at block \ - {published_hash}. The rollup was subscribed to the slot index and the \ - slot header has been confirmed at {confirmed_hash}. The slot contents \ - will be downloaded." - ~level:Notice - ("slot_index", Dal.Slot_index.encoding) - ("published_hash", Block_hash.encoding) - ("confirmed_hash", Block_hash.encoding) -end - -let slot_has_been_confirmed slot published_hash confirmed_hash = - Simple.(emit slot_has_been_confirmed (slot, published_hash, confirmed_hash)) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dune b/src/proto_015_PtLimaPt/bin_sc_rollup_node/dune deleted file mode 100644 index 14d1807fcbd38b9facd8a7f31d10b24966197f5e..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/dune +++ /dev/null @@ -1,59 +0,0 @@ -; This file was automatically generated, do not edit. -; Edit file manifest/main.ml instead. - -(executable - (name main_sc_rollup_node_015_PtLimaPt) - (public_name octez-sc-rollup-node-PtLimaPt) - (package octez-sc-rollup-node-PtLimaPt) - (instrumentation (backend bisect_ppx)) - (libraries - tezos-base - tezos-clic - tezos-client-commands - tezos-stdlib-unix - tezos-client-base - tezos-client-base-unix - tezos-client-015-PtLimaPt - tezos-context.encoding - tezos-context.helpers - tezos-protocol-015-PtLimaPt - tezos-protocol-plugin-015-PtLimaPt - tezos-protocol-015-PtLimaPt.parameters - tezos-rpc - tezos-rpc-http - tezos-rpc-http-server - tezos_dal_node_services - tezos-shell-services - tezos-sc-rollup-015-PtLimaPt - tezos-layer2-utils-015-PtLimaPt - tezos_layer2_store - data-encoding - irmin-pack - irmin-pack.unix - irmin - ringo - ringo-lwt - tezos-injector-015-PtLimaPt - tezos-scoru-wasm) - (link_flags - (:standard) - (:include %{workspace_root}/static-link-flags.sexp)) - (flags - (:standard) - -open Tezos_base.TzPervasives - -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals - -open Tezos_clic - -open Tezos_client_commands - -open Tezos_stdlib_unix - -open Tezos_client_base - -open Tezos_client_base_unix - -open Tezos_client_015_PtLimaPt - -open Tezos_protocol_015_PtLimaPt - -open Tezos_protocol_plugin_015_PtLimaPt - -open Tezos_protocol_015_PtLimaPt_parameters - -open Tezos_rpc - -open Tezos_shell_services - -open Tezos_sc_rollup_015_PtLimaPt - -open Tezos_layer2_utils_015_PtLimaPt - -open Tezos_layer2_store - -open Tezos_injector_015_PtLimaPt)) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/event.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/event.ml deleted file mode 100644 index 674397d5618109654915b9f57a346410d2f05ab0..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/event.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. *) -(* *) -(*****************************************************************************) - -module Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"] - - let starting_node = - declare_0 - ~section - ~name:"starting_sc_rollup_node" - ~msg:"Starting the smart contract rollup node" - ~level:Notice - () - - let shutdown_node = - declare_1 - ~section - ~name:"stopping_sc_rollup_node" - ~msg:"Stopping the smart contract rollup node" - ~level:Notice - ("exit_status", Data_encoding.int8) - - let node_is_ready = - declare_2 - ~section - ~name:"sc_rollup_node_is_ready" - ~msg:"The smart contract rollup node is listening to {addr}:{port}" - ~level:Notice - ("addr", Data_encoding.string) - ("port", Data_encoding.uint16) - - let rollup_exists = - declare_2 - ~section - ~name:"sc_rollup_node_knows_its_rollup" - ~msg: - "The smart contract rollup node is interacting with rollup {addr} of \ - kind {kind}" - ~level:Notice - ("addr", Protocol.Alpha_context.Sc_rollup.Address.encoding) - ("kind", Data_encoding.string) - - let connection_lost = - declare_0 - ~section - ~name:"sc_rollup_daemon_connection_lost" - ~msg:"connection to the node has been lost" - ~level:Warning - () - - let cannot_connect = - declare_2 - ~section - ~name:"sc_rollup_daemon_cannot_connect" - ~msg:"cannot connect to Tezos node ({count}) {error}" - ~level:Warning - ("count", Data_encoding.int31) - ("error", trace_encoding) - ~pp2:pp_print_trace - - let wait_reconnect = - declare_1 - ~section - ~name:"sc_rollup_daemon_wait_reconnect" - ~msg:"Retrying to connect in {delay}s" - ~level:Warning - ("delay", Data_encoding.float) -end - -let starting_node = Simple.(emit starting_node) - -let shutdown_node exit_status = Simple.(emit shutdown_node exit_status) - -let node_is_ready ~rpc_addr ~rpc_port = - Simple.(emit node_is_ready (rpc_addr, rpc_port)) - -let rollup_exists ~addr ~kind = - let kind = Protocol.Alpha_context.Sc_rollup.Kind.name_of kind in - Simple.(emit rollup_exists (addr, kind)) - -let connection_lost () = Simple.(emit connection_lost) () - -let cannot_connect ~count error = Simple.(emit cannot_connect) (count, error) - -let wait_reconnect delay = Simple.(emit wait_reconnect) delay diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/event.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/event.mli deleted file mode 100644 index 0f08859e9bb5de80de68f3af435fb9cc4b8f3679..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/event.mli +++ /dev/null @@ -1,53 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 functions that emit the events used when the smart - contract rollup node is running (see {!Daemon}). *) - -open Protocol.Alpha_context - -val starting_node : unit -> unit Lwt.t - -val node_is_ready : rpc_addr:string -> rpc_port:int -> unit Lwt.t - -(** [rollup_exists addr kind] emits the event that the smart contract rollup - node is interacting with the rollup at address [addr] and of the given - [kind]. *) -val rollup_exists : addr:Sc_rollup.t -> kind:Sc_rollup.Kind.t -> unit Lwt.t - -(** [shutdown_node exit_status] emits the event that the smart contract rollup - node is stopping with exit status [exit_status]. *) -val shutdown_node : int -> unit Lwt.t - -(** Emits the event that the connection to the Tezos node has been lost. *) -val connection_lost : unit -> unit Lwt.t - -(** [cannot_connect ~count error] emits the event that the rollup node cannot - connect to the Tezos node because of [error] for the [count]'s time. *) -val cannot_connect : count:int -> tztrace -> unit Lwt.t - -(** [wait_reconnect delay] emits the event that the rollup will wait [delay] - seconds before attempting to reconnect to the Tezos node . *) -val wait_reconnect : float -> unit Lwt.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox.ml deleted file mode 100644 index 31f3f208cfe86070922bf46cd70d495bc69f98d5..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox.ml +++ /dev/null @@ -1,233 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 Constants will be shadowed by Alpha_context.Constansts - once we open Alpha_context, hence we we alias it to Rollup_node_constants -*) -open Protocol -open Alpha_context - -let lift = Lwt.map Environment.wrap_tzresult - -let head_processing_failure e = - Format.eprintf - "Error during head processing: @[%a@]" - Error_monad.(TzTrace.pp_print_top pp) - e ; - Lwt_exit.exit_and_raise 1 - -module State = struct - let add_messages = Store.Messages.add - - let add_inbox = Store.Inboxes.add - - let add_history = Store.Histories.add - - (** [inbox_of_hash node_ctxt store block_hash] returns the latest - inbox at the given [block_hash]. This function always returns - [Some inbox] for all levels after the rollup genesis even when - no messages has been issued at this specific [block_hash]. In - this case, the inbox is the same as the one found in the level - when the latest message has been inserted. *) - let inbox_of_hash node_ctxt block_hash = - let open Lwt_result_syntax in - let open Node_context in - let*! possible_inbox = Store.Inboxes.find node_ctxt.store block_hash in - match possible_inbox with - | None -> - (* We won't find inboxes for blocks before the rollup origination level. - Fortunately this case will only ever be called once when dealing with - the rollup origination block. After that we would always find an - inbox. *) - let*! block_level = Layer1.level_of_hash node_ctxt.store block_hash in - let block_level = Raw_level.of_int32_exn block_level in - if Raw_level.(block_level <= node_ctxt.genesis_info.level) then - let*! inbox = - Context.Inbox.empty - node_ctxt.context - node_ctxt.rollup_address - node_ctxt.genesis_info.level - in - return inbox - else - failwith - "The inbox for block hash %a (level = %a) is missing." - Block_hash.pp - block_hash - Raw_level.pp - block_level - | Some inbox -> return inbox - - let history_of_hash node_ctxt block_hash = - let open Lwt_result_syntax in - let open Node_context in - let*! res = Store.Histories.find node_ctxt.store block_hash in - match res with - | Some history -> return history - | None -> - (* We won't find inboxes for blocks before the rollup origination level. - Fortunately this case will only ever be called once when dealing with - the rollup origination block. After that we would always find an - inbox. *) - let*! block_level = Layer1.level_of_hash node_ctxt.store block_hash in - let block_level = Raw_level.of_int32_exn block_level in - if Raw_level.(block_level <= node_ctxt.genesis_info.level) then - return @@ Sc_rollup.Inbox.History.empty ~capacity:60000L - else - failwith - "The inbox history for hash %a is missing." - Block_hash.pp - block_hash -end - -let get_messages Node_context.{l1_ctxt; rollup_address; _} head = - let open Lwt_result_syntax in - let* block = Layer1.fetch_tezos_block l1_ctxt head in - let apply (type kind) accu ~source:_ (operation : kind manager_operation) - _result = - let open Result_syntax in - let+ accu = accu in - match operation with - | Sc_rollup_add_messages {rollup; messages} - when Sc_rollup.Address.(rollup = rollup_address) -> - let messages = - List.map - (fun message -> Sc_rollup.Inbox_message.External message) - messages - in - List.rev_append messages accu - | _ -> accu - in - let apply_internal (type kind) accu ~source - (operation : kind Apply_internal_results.internal_operation) - (result : - kind Apply_internal_results.successful_internal_operation_result) = - let open Result_syntax in - let* accu = accu in - match (operation, result) with - | ( { - operation = Transaction {destination = Sc_rollup rollup; parameters; _}; - source = Originated sender; - _; - }, - ITransaction_result (Transaction_to_sc_rollup_result _) ) - when Sc_rollup.Address.(rollup = rollup_address) -> - let+ payload = - Environment.wrap_tzresult @@ Script_repr.force_decode parameters - in - let message = Sc_rollup.Inbox_message.{payload; sender; source} in - Sc_rollup.Inbox_message.Internal message :: accu - | _ -> return accu - in - let*? messages = - Layer1_services.( - process_applied_manager_operations - (Ok []) - block.operations - {apply; apply_internal}) - in - return (List.rev messages) - -let same_inbox_as_layer_1 node_ctxt head_hash inbox = - let open Lwt_result_syntax in - let head_block = `Hash (head_hash, 0) in - let Node_context.{cctxt; rollup_address; _} = node_ctxt in - let* layer1_inbox = - Plugin.RPC.Sc_rollup.inbox cctxt (cctxt#chain, head_block) rollup_address - in - fail_unless - (Sc_rollup.Inbox.equal layer1_inbox inbox) - (Sc_rollup_node_errors.Inconsistent_inbox {layer1_inbox; inbox}) - -let process_head node_ctxt Layer1.(Head {level; hash = head_hash} as head) = - let open Lwt_result_syntax in - let*! res = get_messages node_ctxt head_hash in - match res with - | Error e -> head_processing_failure e - | Ok messages -> - let*! () = - Inbox_event.get_messages head_hash level (List.length messages) - in - let*! () = State.add_messages node_ctxt.store head_hash messages in - (* - - We compute the inbox of this block using the inbox of its - predecessor. That way, the computation of inboxes is robust - to chain reorganization. - - *) - let*! predecessor = Layer1.predecessor node_ctxt.store head in - let* inbox = State.inbox_of_hash node_ctxt predecessor in - let* history = State.history_of_hash node_ctxt predecessor in - let* ctxt = - if level <= Raw_level.to_int32 node_ctxt.Node_context.genesis_info.level - then - (* This is before we have interpreted the boot sector, so we start - with an empty context in genesis *) - return (Context.empty node_ctxt.context) - else Node_context.checkout_context node_ctxt predecessor - in - let*! messages_tree = Context.MessageTrees.find ctxt in - let* history, inbox, ctxt = - lift - @@ let*? level = Raw_level.of_int32 level in - let*? messages = - List.map_e Sc_rollup.Inbox_message.serialize messages - in - if messages = [] then return (history, inbox, ctxt) - else - let commitment_period = - node_ctxt.protocol_constants.parametric.sc_rollup - .commitment_period_in_blocks |> Int32.of_int - in - let inbox = - Sc_rollup.Inbox.refresh_commitment_period - ~commitment_period - ~level - inbox - in - let* messages_tree, history, inbox = - Context.Inbox.add_messages - node_ctxt.context - history - inbox - level - messages - messages_tree - in - - let*! ctxt = Context.MessageTrees.set ctxt messages_tree in - return (history, inbox, ctxt) - in - let* () = same_inbox_as_layer_1 node_ctxt head_hash inbox in - let*! () = State.add_inbox node_ctxt.store head_hash inbox in - let*! () = State.add_history node_ctxt.store head_hash history in - return ctxt - -let inbox_of_hash = State.inbox_of_hash - -let history_of_hash = State.history_of_hash - -let start () = Inbox_event.starting () diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox.mli deleted file mode 100644 index b9895ae2bec97b850541b09c9a73d181b0c03e2b..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox.mli +++ /dev/null @@ -1,54 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 rollup node maintains an inbox of incoming messages. - - The incoming messages for a rollup are published on the layer 1. To - maintain the state of its inbox, a rollup node retrieves these - messages each time the tezos blockchain is updated. - - The inbox state is persistent. - -*) - -open Protocol.Alpha_context - -(** [process_head node_ctxt head operations] changes the state of the inbox to - react to [head]. In particular, this process filters the provided - [operations] of the [head] block. *) -val process_head : Node_context.t -> Layer1.head -> Context.t tzresult Lwt.t - -(** [inbox_of_hash node_ctxt block_hash] returns the rollup inbox at the end of - the given validation of [block_hash]. *) -val inbox_of_hash : - Node_context.t -> Block_hash.t -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** [history_of_hash node_ctxt block_hash] returns the rollup inbox history at - the end of the given validation of [block_hash]. *) -val history_of_hash : - Node_context.t -> Block_hash.t -> Sc_rollup.Inbox.History.t tzresult Lwt.t - -(** [start ()] initializes the inbox to track the messages being published. *) -val start : unit -> unit Lwt.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox_event.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox_event.ml deleted file mode 100644 index 36464fa0453fc72de9d72ddbba770f2ff4f39937..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox_event.ml +++ /dev/null @@ -1,65 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; "inbox"] - - let starting = - declare_0 - ~section - ~name:"sc_rollup_node_inbox_starting" - ~msg:"Starting inbox tracker of the smart contract rollup node" - ~level:Notice - () - - let stopping = - declare_0 - ~section - ~name:"sc_rollup_node_inbox_stopping" - ~msg:"Stopping inbox tracker of the smart contract rollup node" - ~level:Notice - () - - let get_messages = - declare_3 - ~section - ~name:"sc_rollup_node_layer_1_get_messages" - ~msg: - "Fetching {number_of_messages} messages from block {hash} at level \ - {level}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) - ("number_of_messages", Data_encoding.int32) -end - -let starting = Simple.(emit starting) - -let stopping = Simple.(emit stopping) - -let get_messages hash level number_of_messages = - Simple.(emit get_messages (hash, level, Int32.of_int number_of_messages)) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox_event.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox_event.mli deleted file mode 100644 index 72a3b8200880eadedfe867fec3747d53a9e7d5be..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/inbox_event.mli +++ /dev/null @@ -1,35 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 functions that emit the events used by the rollup node - for incoming messages (see {!Inbox}). *) - -val starting : unit -> unit Lwt.t - -val stopping : unit -> unit Lwt.t - -(** [get_messages hash level n] emits the event that [n] messages are being - fetched from the block of the given [hash] at the given [level]. *) -val get_messages : Block_hash.t -> int32 -> int -> unit Lwt.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/injector.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/injector.ml deleted file mode 100644 index 982460e53953e6c87c7999ab26577bf922975ea7..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/injector.ml +++ /dev/null @@ -1,169 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 -open Injector_sigs - -module Parameters : - PARAMETERS - with type rollup_node_state = Node_context.t - and type Tag.t = Configuration.purpose = struct - type rollup_node_state = Node_context.t - - let events_section = ["sc_rollup.injector"] - - module Tag : TAG with type t = Configuration.purpose = struct - type t = Configuration.purpose - - let compare = Stdlib.compare - - let equal = Stdlib.( = ) - - let hash = Hashtbl.hash - - let string_of_tag = Configuration.string_of_purpose - - let pp ppf t = Format.pp_print_string ppf (string_of_tag t) - - let encoding : t Data_encoding.t = - let open Data_encoding in - string_enum - (List.map (fun t -> (string_of_tag t, t)) Configuration.purposes) - end - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3459 - Very coarse approximation for the number of operation we - expect for each block *) - let table_estimated_size : Tag.t -> int = function - | Publish -> 1 - | Add_messages -> 100 - | Cement -> 1 - | Timeout -> 1 - | Refute -> 1 - - let operation_tag (type kind) (operation : kind manager_operation) : - Tag.t option = - match operation with - | Sc_rollup_add_messages _ -> Some Add_messages - | Sc_rollup_cement _ -> Some Cement - | Sc_rollup_publish _ -> Some Publish - | Sc_rollup_timeout _ -> Some Timeout - | Sc_rollup_refute _ -> Some Refute - | _ -> None - - let fee_parameter node_ctxt operation = - match operation_tag operation with - | None -> Configuration.default_fee_parameter () - | Some tag -> Node_context.get_fee_parameter node_ctxt tag - - (* Below are dummy values that are only used to approximate the - size. It is thus important that they remain above the real - values if we want the computed size to be an over_approximation - (without having to do a simulation first). *) - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3461 - Fee parameter per operation. - - See TORU issue: https://gitlab.com/tezos/tezos/-/issues/2812 - check the size, or compute them wrt operation kind *) - let approximate_fee_bound _ _ = - { - fee = Tez.of_mutez_exn 3_000_000L; - counter = Z.of_int 500_000; - gas_limit = Gas.Arith.integral_of_int_exn 500_000; - storage_limit = Z.of_int 500_000; - } - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3459 - Decide if some batches must have all the operations succeed. See - {!Injector_sigs.Parameter.batch_must_succeed}. *) - let batch_must_succeed _ = `At_least_one - - let ignore_failing_operation : - type kind. - kind manager_operation -> [`Ignore_keep | `Ignore_drop | `Don't_ignore] = - function - | Sc_rollup_timeout _ | Sc_rollup_refute _ -> - (* Failing timeout and refutation operations can be ignored. *) - `Ignore_drop - | _ -> `Don't_ignore - - (** Returns [true] if an included operation should be re-queued for injection - when the block in which it is included is reverted (due to a - reorganization). *) - let requeue_reverted_operation (type kind) _node_ctxt - (operation : kind manager_operation) = - let open Lwt_syntax in - match operation with - | Sc_rollup_publish _ -> - (* Commitments are always produced on finalized blocks. They don't need - to be recomputed, and as such are valid in another branch. *) - return_true - | Sc_rollup_cement _ -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3348 - The cementation operations should be re-injected because the node only - keeps track of the last cemented level and the last published - commitment, without rollbacks. - *) - return_true - | Sc_rollup_add_messages _ -> - (* Messages posted to an inbox should be re-emitted (i.e. re-queued) in - case of a fork. *) - return_true - | Sc_rollup_timeout _ -> - (* Timeout should be re-submitted as the timeout may be reached as well - on the other branch *) - return_true - | Sc_rollup_refute _ -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3459 - maybe check if game exists on other branch as well. - - Refutation should be re-submitted in case of fork. - *) - return_true - | Reveal _ | Transaction _ | Origination _ | Delegation _ - | Update_consensus_key _ | Register_global_constant _ | Set_deposits_limit _ - | Increase_paid_storage _ | Tx_rollup_origination | Tx_rollup_submit_batch _ - | Tx_rollup_commit _ | Tx_rollup_return_bond _ - | Tx_rollup_finalize_commitment _ | Tx_rollup_remove_commitment _ - | Tx_rollup_rejection _ | Tx_rollup_dispatch_tickets _ | Transfer_ticket _ - | Dal_publish_slot_header _ | Sc_rollup_originate _ - | Sc_rollup_execute_outbox_message _ | Sc_rollup_recover_bond _ - | Sc_rollup_dal_slot_subscribe _ | Zk_rollup_origination _ - | Zk_rollup_publish _ -> - (* These operations should never be handled by this injector *) - assert false - - let operation_tag (type kind) (operation : kind manager_operation) : - Tag.t option = - match operation with - | Sc_rollup_add_messages _ -> Some Add_messages - | Sc_rollup_cement _ -> Some Cement - | Sc_rollup_publish _ -> Some Publish - | Sc_rollup_timeout _ -> Some Timeout - | Sc_rollup_refute _ -> Some Refute - | _ -> None -end - -include Injector_functor.Make (Parameters) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/injector.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/injector.mli deleted file mode 100644 index c08bb06e06d7f07debf10827f5925e98764a73e8..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/injector.mli +++ /dev/null @@ -1,29 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 - Injector_sigs.S - with type rollup_node_state := Node_context.t - and type tag := Configuration.purpose diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/interpreter.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/interpreter.ml deleted file mode 100644 index 4844dee6b44b652c3bb55003177701894577286b..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/interpreter.ml +++ /dev/null @@ -1,369 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 Inbox = Sc_rollup.Inbox - -module type S = sig - module PVM : Pvm.S - - (** [process_head node_ctxt head] interprets the messages associated - with a [head] from a chain [event]. This requires the inbox to be updated - beforehand. *) - val process_head : - Node_context.t -> Context.t -> Layer1.head -> unit tzresult Lwt.t - - (** [state_of_tick node_ctxt tick level] returns [Some (state, hash)] - for a given [tick] if this [tick] happened before - [level]. Otherwise, returns [None].*) - val state_of_tick : - Node_context.t -> - Sc_rollup.Tick.t -> - Raw_level.t -> - (PVM.state * PVM.hash) option tzresult Lwt.t -end - -module Make (PVM : Pvm.S) : S with module PVM = PVM = struct - module PVM = PVM - module Interpreter_event = Interpreter_event.Make (PVM) - - let consume_fuel = Option.map pred - - let continue_with_fuel fuel state f = - let open Lwt_result_syntax in - match fuel with - | Some 0 -> return (state, fuel) - | _ -> f (consume_fuel fuel) state - - (** [eval_until_input level message_index ~fuel start_tick - failing_ticks state] advances a PVM [state] until it wants more - inputs or there are no more [fuel] (if [Some fuel] is - specified). The evaluation is running under the processing of - some [message_index] at a given [level] and this is the - [start_tick] of this message processing. If some [failing_ticks] - are planned by the loser mode, they will be made. *) - let eval_until_input data_dir level message_index ~fuel start_tick - failing_ticks state = - let open Lwt_result_syntax in - let eval_tick tick failing_ticks state = - let normal_eval state = - let*! state = PVM.eval state in - return (state, failing_ticks) - in - let failure_insertion_eval state failing_ticks' = - let*! () = - Interpreter_event.intended_failure - ~level - ~message_index - ~message_tick:tick - ~internal:true - in - let*! state = PVM.Internal_for_tests.insert_failure state in - return (state, failing_ticks') - in - match failing_ticks with - | xtick :: failing_ticks' when xtick = tick -> - failure_insertion_eval state failing_ticks' - | _ -> normal_eval state - in - let rec go fuel tick failing_ticks state = - let*! input_request = PVM.is_input_state state in - match fuel with - | Some 0 -> return (state, fuel, tick, failing_ticks) - | None | Some _ -> ( - match input_request with - | No_input_required -> - let* next_state, failing_ticks = - eval_tick tick failing_ticks state - in - go (consume_fuel fuel) (tick + 1) failing_ticks next_state - | Needs_reveal (Reveal_raw_data hash) -> ( - match Reveals.get ~data_dir ~pvm_name:PVM.name ~hash with - | None -> - tzfail (Sc_rollup_node_errors.Cannot_retrieve_reveal hash) - | Some data -> - let*! next_state = - PVM.set_input (Reveal (Raw_data data)) state - in - go (consume_fuel fuel) (tick + 1) failing_ticks next_state) - | _ -> return (state, fuel, tick, failing_ticks)) - in - go fuel start_tick failing_ticks state - - (** [mutate input] corrupts the payload of [input] for testing purposes. *) - let mutate input = - let payload = Sc_rollup.Inbox_message.unsafe_of_string "0xC4C4" in - {input with Sc_rollup.payload} - - (** [feed_input level message_index ~fuel ~failing_ticks state - input] feeds [input] (that has a given [message_index] in inbox - of [level]) to the PVM in order to advance [state] to the next - step that requires an input. This function is controlled by - some [fuel] and may introduce intended failures at some given - [failing_ticks]. *) - let feed_input data_dir level message_index ~fuel ~failing_ticks state input = - let open Lwt_result_syntax in - let* state, fuel, tick, failing_ticks = - eval_until_input data_dir level message_index ~fuel 0 failing_ticks state - in - continue_with_fuel fuel state @@ fun fuel state -> - let* input, failing_ticks = - match failing_ticks with - | xtick :: failing_ticks' -> - if xtick = tick then - let*! () = - Interpreter_event.intended_failure - ~level - ~message_index - ~message_tick:tick - ~internal:false - in - return (mutate input, failing_ticks') - else return (input, failing_ticks) - | _ -> return (input, failing_ticks) - in - let*! state = PVM.set_input (Inbox_message input) state in - let* state, fuel, _tick, _failing_ticks = - eval_until_input - data_dir - level - message_index - ~fuel - tick - failing_ticks - state - in - return (state, fuel) - - let eval_block_inbox data_dir ?fuel failures store hash state = - let open Lwt_result_syntax in - (* Obtain inbox and its messages for this block. *) - let*! inbox = Store.Inboxes.find store hash in - match inbox with - | None -> - (* A level with no messages for use. Skip it. *) - let*! level = Layer1.level_of_hash store hash in - return (state, Z.zero, Raw_level.of_int32_exn level, fuel) - | Some inbox -> - let inbox_level = Inbox.inbox_level inbox in - let*! messages = Store.Messages.get store hash in - (* TODO: #2717 - The length of messages here can potentially overflow the [int] returned from [List.length]. - *) - let num_messages = List.length messages |> Z.of_int in - (* Iterate the PVM state with all the messages for this level. *) - let* state, fuel = - List.fold_left_i_es - (fun message_counter (state, fuel) message -> - let*? payload = - Sc_rollup.Inbox_message.( - message |> serialize |> Environment.wrap_tzresult) - in - let input = - Sc_rollup. - { - inbox_level; - message_counter = Z.of_int message_counter; - payload; - } - in - let level = Raw_level.to_int32 inbox_level |> Int32.to_int in - let failing_ticks = - Loser_mode.is_failure - failures - ~level - ~message_index:message_counter - in - let* state, fuel = - feed_input - data_dir - level - message_counter - ~fuel - ~failing_ticks - state - input - in - return (state, fuel)) - (state, fuel) - messages - in - return (state, num_messages, inbox_level, fuel) - - let genesis_state block_hash node_ctxt ctxt = - let open Node_context in - let open Lwt_result_syntax in - let* boot_sector = - Plugin.RPC.Sc_rollup.boot_sector - node_ctxt.cctxt - (node_ctxt.cctxt#chain, `Hash (block_hash, 0)) - node_ctxt.rollup_address - in - let*! initial_state = PVM.initial_state node_ctxt.context in - let*! genesis_state = PVM.install_boot_sector initial_state boot_sector in - let*! ctxt = PVM.State.set ctxt genesis_state in - return (ctxt, genesis_state) - - let state_of_hash node_ctxt ctxt hash level = - let open Lwt_result_syntax in - if Raw_level.(level = node_ctxt.Node_context.genesis_info.level) then - genesis_state hash node_ctxt ctxt - else - let*! state = PVM.State.find ctxt in - match state with - | None -> tzfail (Sc_rollup_node_errors.Missing_PVM_state (hash, level)) - | Some state -> return (ctxt, state) - - (** [transition_pvm node_ctxt predecessor_hash head] runs a PVM at the - previous state from block [predecessor_hash] by consuming as many messages - as possible from block [head]. *) - let transition_pvm node_ctxt ctxt predecessor_hash (Layer1.Head {hash; level}) - = - let open Lwt_result_syntax in - let data_dir = node_ctxt.Node_context.data_dir in - (* Retrieve the previous PVM state from store. *) - let pred_level = Int32.pred level |> Raw_level.of_int32_exn in - let* ctxt, predecessor_state = - if Raw_level.(pred_level <= node_ctxt.Node_context.genesis_info.level) - then genesis_state hash node_ctxt ctxt - else state_of_hash node_ctxt ctxt predecessor_hash pred_level - in - let* state, num_messages, inbox_level, _fuel = - eval_block_inbox - data_dir - node_ctxt.loser_mode - node_ctxt.store - hash - predecessor_state - in - - (* Write final state to store. *) - let*! ctxt = PVM.State.set ctxt state in - let*! context_hash = Context.commit ctxt in - let*! () = Store.Contexts.add node_ctxt.store hash context_hash in - - (* Compute extra information about the state. *) - let*! initial_tick = PVM.get_tick predecessor_state in - - let*! () = - let open Store.StateHistoryRepr in - let event = - { - tick = initial_tick; - block_hash = hash; - predecessor_hash; - level = inbox_level; - } - in - Store.StateHistory.insert node_ctxt.store event - in - - let*! last_tick = PVM.get_tick state in - (* TODO: #2717 - The number of ticks should not be an arbitrarily-sized integer or - the difference between two ticks should be made an arbitrarily-sized - integer too. - *) - let num_ticks = Sc_rollup.Tick.distance initial_tick last_tick in - let*! () = - Store.StateInfo.add - node_ctxt.store - hash - {num_messages; num_ticks; initial_tick} - in - (* Produce events. *) - let*! () = - Interpreter_event.transitioned_pvm inbox_level state num_messages - in - - return_unit - - (** [process_head node_ctxt head] runs the PVM for the given head. *) - let process_head node_ctxt ctxt head = - let open Lwt_result_syntax in - let*! predecessor_hash = - Layer1.predecessor node_ctxt.Node_context.store head - in - transition_pvm node_ctxt ctxt predecessor_hash head - - (** [run_for_ticks node_ctxt predecessor_hash hash tick_distance] starts the - evaluation of the inbox at block [hash] for at most [tick_distance]. *) - let run_for_ticks node_ctxt predecessor_hash hash level tick_distance = - let open Lwt_result_syntax in - let pred_level = - WithExceptions.Option.get ~loc:__LOC__ (Raw_level.pred level) - in - let* ctxt = Node_context.checkout_context node_ctxt predecessor_hash in - let* _ctxt, state = - state_of_hash node_ctxt ctxt predecessor_hash pred_level - in - let* state, _counter, _level, _fuel = - eval_block_inbox - node_ctxt.data_dir - node_ctxt.loser_mode - ~fuel:tick_distance - node_ctxt.store - hash - state - in - return state - - (** [state_of_tick node_ctxt tick level] returns [Some (state, hash)] for a - given [tick] if this [tick] happened before [level]. Otherwise, returns - [None].*) - let state_of_tick node_ctxt tick level = - let open Lwt_result_syntax in - let* closest_event = - Store.StateHistory.event_of_largest_tick_before - node_ctxt.Node_context.store - tick - in - match closest_event with - | None -> return None - | Some event -> - if Raw_level.(event.level > level) then return None - else - let tick_distance = - Sc_rollup.Tick.distance tick event.tick |> Z.to_int - in - (* TODO: #3384 - We assume that [StateHistory] correctly stores enough - events to compute the state of any tick using - [run_for_ticks]. In particular, this assumes that - [event.block_hash] is the block where the tick - happened. We should test that this is always true because - [state_of_tick] is a critical function. *) - let* state = - run_for_ticks - node_ctxt - event.predecessor_hash - event.block_hash - event.level - tick_distance - in - let*! hash = PVM.state_hash state in - return (Some (state, hash)) -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/interpreter_event.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/interpreter_event.ml deleted file mode 100644 index a6dfa4bfbb0cb7c10b5dc2fc76f0af53684366a8..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/interpreter_event.ml +++ /dev/null @@ -1,71 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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.Sc_rollup - -module Make (PVM : Pvm.S) = struct - module Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; PVM.name; "interpreter"] - - let transitioned_pvm = - declare_4 - ~section - ~name:"sc_rollup_node_interpreter_transitioned_pvm" - ~msg: - "Transitioned PVM at inbox level {inbox_level} to {state_hash} at \ - tick {ticks} with {num_messages} messages" - ~level:Notice - ("inbox_level", Protocol.Alpha_context.Raw_level.encoding) - ("state_hash", State_hash.encoding) - ("ticks", Tick.encoding) - ("num_messages", Data_encoding.z) - - let intended_failure = - declare_4 - ~section - ~name:"sc_rollup_node_interpreter_intended_failure" - ~msg: - "Intended failure at level {level} for message indexed \ - {message_index} and at the tick {message_tick} of message \ - processing (internal = {internal})." - ~level:Notice - ("level", Data_encoding.int31) - ("message_index", Data_encoding.int31) - ("message_tick", Data_encoding.int31) - ("internal", Data_encoding.bool) - end - - let transitioned_pvm inbox_level state num_messages = - let open Lwt_syntax in - let* hash = PVM.state_hash state in - let* ticks = PVM.get_tick state in - Simple.(emit transitioned_pvm (inbox_level, hash, ticks, num_messages)) - - let intended_failure ~level ~message_index ~message_tick ~internal = - Simple.( - emit intended_failure (level, message_index, message_tick, internal)) -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/interpreter_event.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/interpreter_event.mli deleted file mode 100644 index fc6634f76b05f9a441c0d750da7e35775657320b..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/interpreter_event.mli +++ /dev/null @@ -1,49 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 functions that emit the events used when running a PVM - transition (see {!Interpreter}). *) - -module Make (PVM : Pvm.S) : sig - (** [transition_pvm inbox_level hash n] emits the event that a PVM - transition is leading to the state of the given [hash] by - processing [n] messages. *) - val transitioned_pvm : - Protocol.Alpha_context.Raw_level.t -> PVM.state -> Z.t -> unit Lwt.t - - (** [intended_failure level message_index message_tick internal] emits - the event that an intended failure has been injected at some given - [level], during the processing of a given [message_index] and at - tick [message_tick] during this message processing. [internal] is - [true] if the failure is injected in a PVM internal - step. [internal] is [false] if the failure is injected in the input - to the PVM. *) - val intended_failure : - level:int -> - message_index:int -> - message_tick:int -> - internal:bool -> - unit Lwt.t -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1.ml deleted file mode 100644 index 203d967505ccb9a8e6e0494477f461e42eb4ff96..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1.ml +++ /dev/null @@ -1,561 +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 Configuration -open Protocol.Alpha_context -open Plugin -open Injector_common - -(** - - Errors - ====== - -*) -let synchronization_failure e = - Format.eprintf - "Error during synchronization: @[%a@]" - Error_monad.(TzTrace.pp_print_top pp) - e ; - Lwt_exit.exit_and_raise 1 - -type error += Cannot_find_block of Block_hash.t - -let () = - register_error_kind - ~id:"sc_rollup.node.cannot_find_block" - ~title:"Cannot find block from L1" - ~description:"A block couldn't be found from the L1 node" - ~pp:(fun ppf hash -> - Format.fprintf - ppf - "Block with hash %a was not found on the L1 node." - Block_hash.pp - hash) - `Temporary - Data_encoding.(obj1 (req "hash" Block_hash.encoding)) - (function Cannot_find_block hash -> Some hash | _ -> None) - (fun hash -> Cannot_find_block hash) - -(** - - State - ===== - -*) - -type block_hash = Block_hash.t - -type block = Block of {predecessor : block_hash; level : int32} - -let block_encoding = - Data_encoding.( - conv - (fun (Block {predecessor; level}) -> (predecessor, level)) - (fun (predecessor, level) -> Block {predecessor; level}) - (obj2 - (req "predecessor" Block_hash.encoding) - (req "level" Data_encoding.int32))) - -type head = Head of {hash : block_hash; level : int32} - -let head_encoding = - Data_encoding.( - conv - (fun (Head {hash; level}) -> (hash, level)) - (fun (hash, level) -> Head {hash; level}) - (obj2 (req "hash" Block_hash.encoding) (req "level" Data_encoding.int32))) - -module State = struct - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3433 - Check what the actual value of `reorganization_window_length` - should be, and if we want to make it configurable. - *) - let reorganization_window_length = 10 - - module Store = struct - module Blocks = Store_utils.Make_append_only_map (struct - let path = ["tezos"; "blocks"] - - let keep_last_n_entries_in_memory = reorganization_window_length - - type key = block_hash - - let string_of_key = Block_hash.to_b58check - - type value = block - - let value_encoding = block_encoding - end) - - module Head = Store_utils.Make_mutable_value (struct - let path = ["tezos"; "head"] - - type value = head - - let value_encoding = head_encoding - end) - - module Levels = Store_utils.Make_updatable_map (struct - let path = ["tezos"; "levels"] - - let keep_last_n_entries_in_memory = reorganization_window_length - - type key = int32 - - let string_of_key = Int32.to_string - - type value = block_hash - - let value_encoding = Block_hash.encoding - end) - - module ProcessedHashes = Store_utils.Make_append_only_map (struct - let path = ["tezos"; "processed_blocks"] - - let keep_last_n_entries_in_memory = reorganization_window_length - - type key = block_hash - - let string_of_key = Block_hash.to_b58check - - type value = unit - - let value_encoding = Data_encoding.unit - end) - - module LastProcessedHead = Store_utils.Make_mutable_value (struct - let path = ["tezos"; "processed_head"] - - type value = head - - let value_encoding = head_encoding - end) - - module Heads_seen_but_not_finalized = Store_utils.Make_mutable_value (struct - let path = ["heads"; "not_finalized"] - - type value = head list - - let value_encoding = Data_encoding.list head_encoding - end) - end - - let last_seen_head = Store.Head.find - - let set_new_head = Store.Head.set - - let store_block = Store.Blocks.add - - let block_of_hash = Store.Blocks.get - - module Blocks_cache = - Ringo_lwt.Functors.Make_opt - ((val Ringo.( - map_maker ~replacement:LRU ~overflow:Strong ~accounting:Precise)) - (Block_hash)) - - let mark_processed_head store (Head {hash; _} as head) = - let open Lwt_syntax in - let* () = Store.ProcessedHashes.add store hash () in - Store.LastProcessedHead.set store head - - let is_processed = Store.ProcessedHashes.mem - - let last_processed_head = Store.LastProcessedHead.find - - let hash_of_level = Store.Levels.get - - let set_hash_of_level = Store.Levels.add - - let set_heads_not_finalized store heads = - Store.Heads_seen_but_not_finalized.set store heads - - let get_heads_not_finalized store = - let open Lwt_syntax in - let+ heads_opt = Store.Heads_seen_but_not_finalized.find store in - Option.value ~default:[] heads_opt -end - -type blocks_cache = - Protocol_client_context.Alpha_block_services.block_info State.Blocks_cache.t - -(** - - Chain events - ============ - -*) - -type chain_event = - | SameBranch of {new_head : head; intermediate_heads : head list} - | Rollback of {new_head : head} - -let same_branch new_head intermediate_heads = - SameBranch {new_head; intermediate_heads} - -let rollback new_head = Rollback {new_head} - -type t = { - blocks_cache : blocks_cache; - events : chain_event Lwt_stream.t; - cctxt : Protocol_client_context.full; - stopper : RPC_context.stopper; - genesis_info : Sc_rollup.Commitment.genesis_info; -} - -(** - - Helpers - ======= - -*) - -let genesis_hash = - Block_hash.of_b58check_exn - "BLockGenesisGenesisGenesisGenesisGenesisf79b5d1CoW2" - -let chain_event_head_hash = function - | SameBranch {new_head = Head {hash; _}; _} - | Rollback {new_head = Head {hash; _}} -> - hash - -(** [blocks_of_heads base heads] given a list of successive heads - connected to [base], returns an associative list mapping block hash - to block. This list is only used for traversal, not lookup. The - newer blocks come first in that list. *) -let blocks_of_heads base heads = - let rec aux predecessor accu = function - | [] -> accu - | Head {hash; level} :: xs -> - let block = Block {predecessor; level} in - aux hash ((hash, block) :: accu) xs - in - aux base [] heads - -(** [store_chain_event event] updates the persistent state to take a - chain event into account. *) -let store_chain_event store base = - let open Lwt_syntax in - function - | SameBranch {new_head = Head {hash; level} as head; intermediate_heads} -> - let* () = Layer1_event.setting_new_head hash level in - let* () = State.set_new_head store head in - blocks_of_heads base (intermediate_heads @ [head]) - |> List.iter_s (fun (hash, (Block {level; _} as block)) -> - let* () = State.store_block store hash block in - State.set_hash_of_level store level hash) - | Rollback {new_head = Head {hash; level} as base} -> - let* () = Layer1_event.rollback hash level in - State.set_new_head store base - -(** [predecessors_of_blocks hashes] given a list of successive hashes, - returns an associative list that associates a hash to its - predecessor in this list. *) -let predecessors_of_blocks hashes = - let rec aux next = function [] -> [] | x :: xs -> (next, x) :: aux x xs in - match hashes with [] -> [] | x :: xs -> aux x xs - -(** [get_predecessor block_hash] returns the predecessor block hash of - some [block_hash] through an RPC to the Tezos node. To limit the - number of RPCs, this information is requested for a batch of hashes - and cached locally. *) -let get_predecessor = - let max_cached = 1023 and max_read = 8 in - let (module HMF : Ringo.MAP_MAKER) = - Ringo.(map_maker ~replacement:FIFO ~overflow:Strong ~accounting:Precise) - in - let module HM = HMF (Block_hash) in - let cache = HM.create max_cached in - fun cctxt (chain : Tezos_shell_services.Chain_services.chain) ancestor -> - match HM.find_opt cache ancestor with - | Some pred -> Lwt.return (Some pred) - | None -> ( - Tezos_shell_services.Chain_services.Blocks.list - cctxt - ~chain - ~heads:[ancestor] - ~length:max_read - () - >>= function - | Error e -> synchronization_failure e - | Ok blocks -> ( - match blocks with - | [ancestors] -> ( - List.iter - (fun (h, p) -> HM.replace cache h p) - (predecessors_of_blocks ancestors) ; - match HM.find_opt cache ancestor with - | None -> - (* We have just updated the cache with that information. *) - assert false - | Some predecessor -> Lwt.return (Some predecessor)) - | _ -> Lwt.return None)) - -let get_predecessor_head cctxt chain (Head {level; hash}) = - let open Lwt_syntax in - let level = Int32.pred level in - let+ hash' = get_predecessor cctxt chain hash in - Option.map (fun hash' -> Head {level; hash = hash'}) hash' - -(** [catch_up cctxt chain last_seen_head predecessor new_head] - classifies the [new_head] (with some given [predecessor]) in two - distinct categories: - - - If [new_head] has an ancestor which is the [last_seen_head], - returns [SameBranch { new_head; intermediate_heads }] where - [intermediate_heads] are the blocks between [last_seen_head] and - [new_head] in order of increasing levels. - - - If [new_head] has an ancestor that is an ancestor [base] of - [last_seen_head] then returns [Rollback { new_head }]. - - This function also returns the block hash to which the current - branch is rooted. -*) -let catch_up cctxt store chain last_seen_head new_head = - let (Head {hash; _}) = last_seen_head in - - (* [heads] is the list of intermediate heads between - the predecessor of [ancestor] and the [new_head]. [level] - is the level of [ancestor]. *) - let rec aux heads (Head {hash = ancestor_hash; level} as ancestor) = - if Block_hash.equal ancestor_hash hash then - (* We have reconnected to the last seen head. *) - Lwt.return (ancestor_hash, [same_branch new_head heads]) - else - State.is_processed store ancestor_hash >>= function - | true -> - (* We have reconnected to a previously known head. - [new_head] and [last_seen_head] are not the same branch. *) - Lwt.return - (ancestor_hash, [rollback ancestor; same_branch new_head heads]) - | false -> ( - (* We have never seen this head. *) - let heads = ancestor :: heads in - get_predecessor cctxt chain ancestor_hash >>= function - | Some ancestor' when Block_hash.(ancestor_hash <> ancestor') -> - aux heads (Head {level = Int32.pred level; hash = ancestor'}) - | _ -> - (* We have reconnected with the genesis head and it was - unknown until now. *) - Lwt.return (ancestor_hash, [same_branch new_head heads])) - in - get_predecessor_head cctxt chain new_head >>= function - | None -> - (* [new_head] is the genesis head. It is not new. *) - Lwt.return (genesis_hash, []) - | Some predecessor -> aux [] predecessor - -let chain_events cctxt store chain = - let open Lwt_result_syntax in - let on_head (hash, (block_header : Tezos_base.Block_header.t)) = - let level = block_header.shell.level in - let new_head = Head {hash; level} in - let*! last_seen_head = State.last_seen_head store in - let last_seen_head = - match last_seen_head with - | None -> Head {hash = genesis_hash; level = 0l} - | Some last_seen_head -> last_seen_head - in - let*! base, events = catch_up cctxt store chain last_seen_head new_head in - let*! () = List.iter_s (store_chain_event store base) events in - Lwt.return events - in - let+ heads, stopper = - Tezos_shell_services.Monitor_services.heads cctxt chain - in - (Lwt_stream.map_list_s on_head heads, stopper) - -(** [discard_pre_origination_blocks info chain_events] filters [chain_events] in order to - discard all heads that occur before the SC rollup origination. *) -let discard_pre_origination_blocks - (genesis_info : Sc_rollup.Commitment.genesis_info) chain_events = - let origination_level = Raw_level.to_int32 genesis_info.level in - let at_or_after_origination event = - match event with - | SameBranch {new_head = Head {level; _} as new_head; intermediate_heads} - when level >= origination_level -> - let intermediate_heads = - List.filter - (fun (Head {level; _}) -> level >= origination_level) - intermediate_heads - in - Some (SameBranch {new_head; intermediate_heads}) - | Rollback {new_head = Head {level; _}} when level >= origination_level -> - Some event - | _ -> None - in - Lwt_stream.filter_map at_or_after_origination chain_events - -let rec connect ?(count = 0) ~delay cctxt genesis_info store = - let open Lwt_syntax in - let* () = - if count = 0 then return_unit - else - let fcount = float_of_int (count - 1) in - (* Randomized exponential backoff capped to 1.5h: 1.5^count * delay ± 50% *) - let delay = delay *. (1.5 ** fcount) in - let delay = min delay 3600. in - let randomization_factor = 0.5 (* 50% *) in - let delay = - delay - +. Random.float (delay *. 2. *. randomization_factor) - -. (delay *. randomization_factor) - in - let* () = Event.wait_reconnect delay in - Lwt_unix.sleep delay - in - let* res = chain_events cctxt store `Main in - match res with - | Ok (event_stream, stopper) -> - let events = discard_pre_origination_blocks genesis_info event_stream in - return_ok (events, stopper) - | Error e -> - let* () = Event.cannot_connect ~count e in - connect ~delay ~count:(count + 1) cctxt genesis_info store - -let start configuration (cctxt : Protocol_client_context.full) store = - let open Lwt_result_syntax in - let*! () = Layer1_event.starting () in - let* kind = - RPC.Sc_rollup.kind - cctxt - (cctxt#chain, cctxt#block) - configuration.sc_rollup_address - () - in - let*! () = Event.rollup_exists ~addr:configuration.sc_rollup_address ~kind in - let* genesis_info = - RPC.Sc_rollup.genesis_info - cctxt - (cctxt#chain, cctxt#block) - configuration.sc_rollup_address - in - let+ events, stopper = - connect ~delay:configuration.reconnection_delay cctxt genesis_info store - in - ( { - cctxt; - events; - blocks_cache = State.Blocks_cache.create 32; - stopper; - genesis_info; - }, - kind ) - -let reconnect configuration l1_ctxt store = - let open Lwt_result_syntax in - let* events, stopper = - connect - ~count:1 - ~delay:configuration.reconnection_delay - l1_ctxt.cctxt - l1_ctxt.genesis_info - store - in - return {l1_ctxt with events; stopper} - -let current_head_hash store = - let open Lwt_syntax in - let+ head = State.last_seen_head store in - Option.map (fun (Head {hash; _}) -> hash) head - -let current_level store = - let open Lwt_syntax in - let+ head = State.last_seen_head store in - Option.map (fun (Head {level; _}) -> level) head - -let hash_of_level = State.hash_of_level - -let level_of_hash store hash = - let open Lwt_syntax in - let* (Block {level; _}) = State.block_of_hash store hash in - return level - -let predecessor store (Head {hash; _}) = - let open Lwt_syntax in - let+ (Block {predecessor; _}) = State.block_of_hash store hash in - predecessor - -let processed_head (Head {hash; level}) = - Layer1_event.new_head_processed hash level - -let processed = function - | SameBranch {new_head; intermediate_heads} -> - List.iter_s processed_head (intermediate_heads @ [new_head]) - | Rollback {new_head} -> processed_head new_head - -let mark_processed_head store head = State.mark_processed_head store head - -let last_processed_head_hash store = - let open Lwt_syntax in - let+ info = State.last_processed_head store in - Option.map (fun (Head {hash; _}) -> hash) info - -let set_heads_not_finalized = State.set_heads_not_finalized - -let get_heads_not_finalized = State.get_heads_not_finalized - -(* We forget about the last seen heads that are not processed so that - the rollup node can process them when restarted. Notice that this - does prevent skipping heads when the node is interrupted in a bad - way. *) - -(* FIXME: https://gitlab.com/tezos/tezos/-/issues/3205 - - More generally, the rollup node should be able to restart properly - after an abnormal interruption at every point of its process. - Currently, the state is not persistent enough and the processing is - not idempotent enough to achieve that property. *) -let shutdown store = - let open Lwt_syntax in - let* last_processed_head = State.last_processed_head store in - match last_processed_head with - | None -> return_unit - | Some head -> State.set_new_head store head - -(** [fetch_tezos_block l1_ctxt hash] returns a block info given a block - hash. Looks for the block in the blocks cache first, and fetches it from the - L1 node otherwise. *) -let fetch_tezos_block l1_ctxt hash = - trace (Cannot_find_block hash) - @@ fetch_tezos_block - l1_ctxt.cctxt - hash - ~find_in_cache:(State.Blocks_cache.find_or_replace l1_ctxt.blocks_cache) - -(** Returns the reorganization of L1 blocks (if any) for [new_head]. *) -let get_tezos_reorg_for_new_head l1_state store new_head_hash = - let open Lwt_result_syntax in - let*! old_head_hash = current_head_hash store in - match old_head_hash with - | None -> - (* No known tezos head, consider the new head as being on top of a previous - tezos block. *) - let+ new_head = fetch_tezos_block l1_state new_head_hash in - {old_chain = []; new_chain = [new_head]} - | Some old_head_hash -> - tezos_reorg (fetch_tezos_block l1_state) ~old_head_hash ~new_head_hash diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1.mli deleted file mode 100644 index 96080417e396769000bbe788b8ce2cfa36462c38..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1.mli +++ /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. *) -(* *) -(*****************************************************************************) - -(** This module maintains information about the layer 1 chain. - - This module follows the evolution of the layer 1 chain by - subscribing to the head monitoring RPC offered by the Tezos node. - - When started, it provides a stream of events that can be used to be - informed when the head of the layer 1 has changed or when a chain - reorganization occurred. - -*) -type head = Head of {hash : Block_hash.t; level : int32} - -val head_encoding : head Data_encoding.t - -type chain_event = - | SameBranch of {new_head : head; intermediate_heads : head list} - (** The [new_head] follows the current branch. [intermediate_heads] - have been included since the previous synchronization with Tezos - node. *) - | Rollback of {new_head : head} - (** A chain reorganization occurred since the previous - synchronization. The rollback set [new_head] to an old block. *) - -(** Type of cache holding the last 32 blocks, with their operations. *) -type blocks_cache - -type t = private { - blocks_cache : blocks_cache; - events : chain_event Lwt_stream.t; - cctxt : Protocol_client_context.full; - stopper : RPC_context.stopper; - genesis_info : Protocol.Alpha_context.Sc_rollup.Commitment.genesis_info; -} - -val chain_event_head_hash : chain_event -> Block_hash.t - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/3311 - Allow to retrieve L1 blocks through Tezos node storage locally. *) - -(** [start configuration cctxt store] returns a stream of [chain_event] obtained - from the monitoring of the Tezos node set up by the client [cctxt]. The - layer 1 state is stored in the data directory declared in - [configuration]. *) -val start : - Configuration.t -> - Protocol_client_context.full -> - Store.t -> - (t * Protocol.Alpha_context.Sc_rollup.Kind.t) tzresult Lwt.t - -(** [reconnect cfg l1_ctxt store] reconnects (and retries with delay) to the - Tezos node. The delay for each reconnection is increased with a randomized - exponential backoff (capped to 1.5h) . *) -val reconnect : Configuration.t -> t -> Store.t -> t tzresult Lwt.t - -(** [current_head_hash store] is the current hash of the head of the - Tezos chain as far as the smart-contract rollup node knows from the - latest synchronization. Returns [None] if no synchronization has - ever been made. *) -val current_head_hash : Store.t -> Block_hash.t option Lwt.t - -(** [current_level store] is the current level of the Tezos chain as far - as the smart-contract rollup node knows from the latest - synchronization. Returns [None] if no synchronization has ever been - made. *) -val current_level : Store.t -> int32 option Lwt.t - -(** [hash_of_level store level] returns the current block hash for a - given [level]. Raise [Invalid_argument] if [hash] does not belong - to [store]. *) -val hash_of_level : Store.t -> int32 -> Block_hash.t Lwt.t - -(** [level_of_hash store hash] returns the level for a given block - [hash]. Raise [Invalid_argument] if [hash] does not belong to - [store]. *) -val level_of_hash : Store.t -> Block_hash.t -> int32 Lwt.t - -(** [predecessor store head] returns the hash of the head's predecessor block] *) -val predecessor : Store.t -> head -> Block_hash.t Lwt.t - -(** [genesis_hash] is the hash of the genesis block of the chain. *) -val genesis_hash : Block_hash.t - -(** [processed chain_event] emits a log event to officialize the - processing of some layer 1 [chain_event]. *) -val processed : chain_event -> unit Lwt.t - -(** [mark_processed_head store head] remembers that the [head] - is processed. The system should not have to come back to - it. *) -val mark_processed_head : Store.t -> head -> unit Lwt.t - -(** [last_processed_head_hash store] returns the hash of - the last processed head. *) -val last_processed_head_hash : Store.t -> Block_hash.t option Lwt.t - -(** [set_heads_not_finalized store heads] remembers that heads in [heads] - have not been finalized yet, that is for each head in [heads] the rollup - node has never seen another head which is - [(node_ctxt : Node_context).block_finality_time] confirmations ahead. -*) -val set_heads_not_finalized : Store.t -> head list -> unit Lwt.t - -(** [get_heads_not_finalized store] retrieves from [store] - the heads that have not been finalized yet. -*) -val get_heads_not_finalized : Store.t -> head list Lwt.t - -(** [shutdown store] properly shut the layer 1 down. *) -val shutdown : Store.t -> unit Lwt.t - -(** [fetch_tezos_block l1_ctxt hash] returns a block info given a block hash. - Looks for the block in the blocks cache first, and fetches it from the L1 - node otherwise. *) -val fetch_tezos_block : - t -> - Block_hash.t -> - Protocol_client_context.Alpha_block_services.block_info tzresult Lwt.t - -(** [get_tezos_reorg_for_new_head l1_ctxt store hash] returns the reorganization - of L1 blocks (if any) for [new_head]. *) -val get_tezos_reorg_for_new_head : - t -> - Store.t -> - Block_hash.t -> - Protocol_client_context.Alpha_block_services.block_info Injector_common.reorg - tzresult - Lwt.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1_event.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1_event.ml deleted file mode 100644 index 3559bfd6ad38c0e4388361fee299e67d216d18a6..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1_event.ml +++ /dev/null @@ -1,98 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; "layer_1"] - - let starting = - declare_0 - ~section - ~name:"sc_rollup_node_layer_1_starting" - ~msg:"Starting layer 1 tracker of the smart contract rollup node" - ~level:Notice - () - - let stopping = - declare_0 - ~section - ~name:"sc_rollup_node_layer_1_stopping" - ~msg:"Stopping layer 1 tracker of the smart contract rollup node" - ~level:Notice - () - - let setting_new_head = - declare_2 - ~section - ~name:"sc_rollup_node_layer_1_new_head" - ~msg:"Setting layer 1 head to {hash} at level {level}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) - - let rollback = - declare_2 - ~section - ~name:"sc_rollup_node_layer_1_rollback" - ~msg:"Rolling back layer 1 head to {hash} at level {level}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) - - let reacting_to_reorganization = - declare_2 - ~section - ~name:"sc_rollup_node_layer_1_reorganization" - ~msg: - "Reacting to layer 1 reorganization: rollback to {rollback_hash}, \ - process {new_blocks}" - ~level:Notice - ("rollback_hash", Block_hash.encoding) - ("new_blocks", Data_encoding.list Block_hash.encoding) - - let new_head_processed = - declare_2 - ~section - ~name:"sc_rollup_node_layer_1_new_head_processed" - ~msg:"Finished processing layer 1 head {hash} at level {level}" - ~level:Notice - ("hash", Block_hash.encoding) - ("level", Data_encoding.int32) -end - -let starting = Simple.(emit starting) - -let stopping = Simple.(emit stopping) - -let setting_new_head hash level = Simple.(emit setting_new_head (hash, level)) - -let new_head_processed hash level = - Simple.(emit new_head_processed (hash, level)) - -let reacting_to_reorganization h hs = - Simple.(emit reacting_to_reorganization (h, hs)) - -let rollback h hs = Simple.(emit rollback (h, hs)) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1_event.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1_event.mli deleted file mode 100644 index 3531bfd1200321f3a03d69b0d1ae1a5551caf076..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/layer1_event.mli +++ /dev/null @@ -1,48 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 functions that emit the events used by the layer 1 chain - (see {!Layer}). *) - -val starting : unit -> unit Lwt.t - -val stopping : unit -> unit Lwt.t - -(** [rollback hash level] emits the event that the layer 1 head is rolling back - to the block of the given [hash] and at the given [level]. *) -val rollback : Block_hash.t -> int32 -> unit Lwt.t - -(** [setting_new_head hash level] emits the event that the layer 1 head is set - to the block of the given [hash] and at the given [level]. *) -val setting_new_head : Block_hash.t -> int32 -> unit Lwt.t - -(** [new_head_processed hash level] emits the event that the layer 1 head of the - given [hash] and at the given [level] is finished processing. *) -val new_head_processed : Block_hash.t -> int32 -> unit Lwt.t - -(** [reacting_to_reorganization rollbacked_block new_blocks] emits the event - that the rollup node is rolling back to the block of hash [rollbacked_block] - and will be processing the [new_blocks] due to a layer 1 reorganization. *) -val reacting_to_reorganization : Block_hash.t -> Block_hash.t list -> unit Lwt.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/loser_mode.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/loser_mode.ml deleted file mode 100644 index fd2dcc70ce0588bcd29229753aa0d53b2f35da79..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/loser_mode.ml +++ /dev/null @@ -1,76 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 failure = {level : int; message_index : int; message_tick : int} - -let failure_encoding = - let open Data_encoding in - conv - (fun {level; message_index; message_tick} -> - (level, message_index, message_tick)) - (fun (level, message_index, message_tick) -> - {level; message_index; message_tick}) - (obj3 - (req "level" int31) - (req "message_index" int31) - (req "message_tick" int31)) - -let compare_failure {level; message_index; message_tick} f2 = - let open Compare.Int in - match compare level f2.level with - | 0 -> ( - match compare message_index f2.message_index with - | 0 -> compare message_tick f2.message_tick - | n -> n) - | n -> n - -type t = failure list - -let encoding = Data_encoding.list failure_encoding - -let no_failures = [] - -let make s = - let tokens = String.split_on_char ' ' s in - let rec chop = function - | [] | [""] -> [] - | level :: message_index :: message_tick :: rest -> - { - level = int_of_string level; - message_index = int_of_string message_index; - message_tick = int_of_string message_tick; - } - :: chop rest - | _ -> raise Not_found - in - try Some (chop tokens |> List.sort compare_failure) with _ -> None - -let is_failure failures ~level ~message_index = - List.filter_map - (fun f -> - if Compare.Int.(f.level = level && f.message_index = message_index) then - Some f.message_tick - else None) - failures diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/loser_mode.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/loser_mode.mli deleted file mode 100644 index d86a269ee844a2529a13b30e531a068fed52659d..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/loser_mode.mli +++ /dev/null @@ -1,46 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 list of failures. *) -type t - -val encoding : t Data_encoding.t - -(** [no_failures] are planned. *) -val no_failures : t - -(** [make s] parses a list of integers separated by spaces that is a - periodic sequence of triple [level message_index message_tick] - representing a failure that the rollup node is supposed to make. - This function returns [None] if the input string is not syntactically - correct. *) -val make : string -> t option - -(** [is_failure failures ~level ~message_index] returns [message_ticks] - where a failure is supposed to happen at the point - of the rollup node processing of a given inbox [level], a given - [message_index] and for all [message_ticks]. Ticks are sorted by - increasing order. *) -val is_failure : t -> level:int -> message_index:int -> int list diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/main_sc_rollup_node_015_PtLimaPt.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/main_sc_rollup_node_015_PtLimaPt.ml deleted file mode 100644 index acd01d233166c4857b4ba9ae707ad8bedab89ab0..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/main_sc_rollup_node_015_PtLimaPt.ml +++ /dev/null @@ -1,319 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* Copyright (c) 2022 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 sc_rollup_address_param = - Clic.param - ~name:"sc-rollup-address" - ~desc:"The smart-contract rollup address" - (Clic.parameter (fun _ s -> - match Protocol.Alpha_context.Sc_rollup.Address.of_b58check_opt s with - | None -> failwith "Invalid smart-contract rollup address" - | Some addr -> return addr)) - -let sc_rollup_node_operator_param = - let open Lwt_result_syntax in - Clic.param - ~name:"operator" - ~desc: - (Printf.sprintf - "Public key hash, or alias, of a smart-contract rollup node operator. \ - An operator can be specialized to a particular purpose by prefixing \ - its key or alias by said purpose, e.g. publish:alias_of_my_operator. \ - The possible purposes are: %s." - (String.concat ", " - @@ Configuration.(List.map string_of_purpose purposes))) - @@ Clic.parameter - @@ fun cctxt s -> - let parse_pkh s = - let from_alias s = Client_keys.Public_key_hash.find cctxt s in - let from_key s = - match Signature.Public_key_hash.of_b58check_opt s with - | None -> - failwith "Could not read public key hash for rollup node operator" - | Some pkh -> return pkh - in - Client_aliases.parse_alternatives - [("alias", from_alias); ("key", from_key)] - s - in - match String.split ~limit:1 ':' s with - | [_] -> - let+ pkh = parse_pkh s in - `Default pkh - | [purpose; operator_s] -> ( - match Configuration.purpose_of_string purpose with - | Some purpose -> - let+ pkh = parse_pkh operator_s in - `Purpose (purpose, pkh) - | None -> - let+ pkh = parse_pkh s in - `Default pkh) - | _ -> - (* cannot happen due to String.split's implementation. *) - assert false - -let possible_modes = List.map Configuration.string_of_mode Configuration.modes - -let mode_parameter = - Clic.parameter - ~autocomplete:(fun _ -> return possible_modes) - (fun _ m -> Lwt.return (Configuration.mode_of_string m)) - -let mode_param = - Clic.param - ~name:"mode" - ~desc: - (Format.asprintf - "@[The mode for the rollup node (%s)@,%a@]" - (String.concat ", " possible_modes) - (Format.pp_print_list (fun fmt mode -> - Format.fprintf - fmt - "- %s: %s" - (Configuration.string_of_mode mode) - (Configuration.description_of_mode mode))) - Configuration.modes) - mode_parameter - -let rpc_addr_arg = - let default = Configuration.default_rpc_addr in - Clic.default_arg - ~long:"rpc-addr" - ~placeholder:"rpc-address|ip" - ~doc: - (Format.sprintf - "The address the smart-contract rollup node listens to. Default value \ - is %s" - default) - ~default - Client_proto_args.string_parameter - -let dal_node_addr_arg = - let default = Configuration.default_dal_node_addr in - Clic.default_arg - ~long:"dal-node-addr" - ~placeholder:"dal-node-address|ip" - ~doc: - (Format.sprintf - "The address of the dal node from which the smart-contract rollup \ - node downloads slots. Default value is %s" - default) - ~default - Client_proto_args.string_parameter - -let rpc_port_arg = - let default = Configuration.default_rpc_port |> string_of_int in - Clic.default_arg - ~long:"rpc-port" - ~placeholder:"rpc-port" - ~doc: - (Format.sprintf - "The port the smart-contract rollup node listens to. Default value is \ - %s" - default) - ~default - Client_proto_args.int_parameter - -let dal_node_port_arg = - let default = Configuration.default_dal_node_port |> string_of_int in - Clic.default_arg - ~long:"dal-node-port" - ~placeholder:"dal-node-port" - ~doc: - (Format.sprintf - "The port of the dal node from which the smart-contract rollup node \ - downloads slots from. Default value is %s" - default) - ~default - Client_proto_args.int_parameter - -let data_dir_arg = - let default = Configuration.default_data_dir in - Clic.default_arg - ~long:"data-dir" - ~placeholder:"data-dir" - ~doc: - (Format.sprintf - "The path to the smart-contract rollup node data directory. Default \ - value is %s" - default) - ~default - Client_proto_args.string_parameter - -let loser_mode = - Clic.default_arg - ~long:"loser-mode" - ~placeholder:"mode" - ~default:"" - ~doc:"Set the rollup node failure points (for test only!)." - (Clic.parameter (fun _ s -> - match Loser_mode.make s with - | Some t -> return t - | None -> failwith "Invalid syntax for failure points")) - -let reconnection_delay_arg = - let default = - Format.sprintf "%.1f" Configuration.default_reconnection_delay - in - let doc = - Format.asprintf - "The first reconnection delay, in seconds, to wait before reconnecting \ - to the Tezos node. The default delay is %s.\n\ - The actual delay varies to follow a randomized exponential backoff \ - (capped to 1.5h): [1.5^reconnection_attempt * delay ± 50%%]." - default - in - Clic.default_arg - ~long:"reconnection-delay" - ~placeholder:"delay" - ~doc - ~default - (Clic.parameter (fun _ p -> - try return (float_of_string p) with _ -> failwith "Cannot read float")) - -let filename_arg = - Clic.default_arg - ~long:"filename" - ~placeholder:"filename" - ~doc:"The path to the file to import." - ~default:"import.in" - Client_proto_args.string_parameter - -let pvm_name_arg = - Clic.default_arg - ~long:"pvm-name" - ~placeholder:"pvm_name" - ~doc:"The name of the PVM." - ~default:"arith" - Client_proto_args.string_parameter - -let group = - { - Clic.name = "sc_rollup.node"; - title = "Commands related to the smart-contract rollup node."; - } - -let config_init_command = - let open Lwt_result_syntax in - let open Clic in - command - ~group - ~desc:"Configure the smart-contract rollup node." - (args7 - data_dir_arg - rpc_addr_arg - rpc_port_arg - loser_mode - reconnection_delay_arg - dal_node_addr_arg - dal_node_port_arg) - (prefix "init" @@ mode_param - @@ prefixes ["config"; "for"] - @@ sc_rollup_address_param - @@ prefixes ["with"; "operators"] - @@ seq_of_param @@ sc_rollup_node_operator_param) - (fun ( data_dir, - rpc_addr, - rpc_port, - loser_mode, - reconnection_delay, - dal_node_addr, - dal_node_port ) - mode - sc_rollup_address - sc_rollup_node_operators - cctxt -> - let open Configuration in - let purposed_operators, default_operators = - List.partition_map - (function - | `Purpose p_operator -> Left p_operator - | `Default operator -> Right operator) - sc_rollup_node_operators - in - let default_operator = - match default_operators with - | [] -> None - | [default_operator] -> Some default_operator - | _ -> Stdlib.failwith "Multiple default operators" - in - let sc_rollup_node_operators = - Configuration.make_purpose_map - purposed_operators - ~default:default_operator - in - let config = - { - data_dir; - sc_rollup_address; - sc_rollup_node_operators; - rpc_addr; - rpc_port; - reconnection_delay; - dal_node_addr; - dal_node_port; - fee_parameters = Operator_purpose_map.empty; - mode; - loser_mode; - } - in - let*? config = check_mode config in - save config >>=? fun () -> - cctxt#message - "Smart-contract rollup node configuration written in %s" - (filename config) - >>= fun _ -> return ()) - -let run_command = - let open Clic in - command - ~group - ~desc:"Run the rollup daemon." - (args1 data_dir_arg) - (prefixes ["run"] @@ stop) - (fun data_dir cctxt -> Daemon.run ~data_dir cctxt >>=? fun () -> return ()) - -let import_command = - let open Clic in - command - ~group - ~desc:"Run the rollup daemon." - (args3 data_dir_arg filename_arg pvm_name_arg) - (prefixes ["import"] @@ stop) - (fun (data_dir, filename, pvm_name) cctxt -> - let hash = Reveals.import ~data_dir ~filename ~pvm_name in - cctxt#message "%a" Protocol.Alpha_context.Sc_rollup.Input_hash.pp hash - >>= return) - -let sc_rollup_commands () = - List.map - (Clic.map_command (new Protocol_client_context.wrap_full)) - [config_init_command; run_command; import_command] - -let select_commands _ _ = - return (sc_rollup_commands () @ Client_helpers_commands.commands ()) - -let () = Client_main_run.run (module Daemon_config) ~select_commands diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/node_context.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/node_context.ml deleted file mode 100644 index 18c6b8cadf48de3927280748da781549b4974df8..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/node_context.ml +++ /dev/null @@ -1,103 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 = { - cctxt : Protocol_client_context.full; - dal_cctxt : Dal_node_client.cctxt; - data_dir : string; - l1_ctxt : Layer1.t; - rollup_address : Sc_rollup.t; - operators : Configuration.operators; - genesis_info : Sc_rollup.Commitment.genesis_info; - block_finality_time : int; - kind : Sc_rollup.Kind.t; - fee_parameters : Configuration.fee_parameters; - protocol_constants : Constants.t; - loser_mode : Loser_mode.t; - store : Store.t; - context : Context.index; -} - -let get_operator node_ctxt purpose = - Configuration.Operator_purpose_map.find purpose node_ctxt.operators - -let is_operator node_ctxt pkh = - Configuration.Operator_purpose_map.exists - (fun _ operator -> Signature.Public_key_hash.(operator = pkh)) - node_ctxt.operators - -let get_fee_parameter node_ctxt purpose = - Configuration.Operator_purpose_map.find purpose node_ctxt.fee_parameters - |> Option.value ~default:(Configuration.default_fee_parameter ~purpose ()) - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2901 - The constants are retrieved from the latest tezos block. These constants can - be different from the ones used at the creation at the rollup because of a - protocol amendment that modifies some of them. This need to be fixed when the - rollup nodes will be able to handle the migration of protocol. -*) -let retrieve_constants cctxt = - Protocol.Constants_services.all cctxt (cctxt#chain, cctxt#block) - -let init (cctxt : Protocol_client_context.full) dal_cctxt ~data_dir l1_ctxt - rollup_address kind operators fee_parameters ~loser_mode store context = - let open Lwt_result_syntax in - let+ protocol_constants = retrieve_constants cctxt in - { - cctxt; - dal_cctxt; - data_dir; - l1_ctxt; - rollup_address; - operators; - genesis_info = l1_ctxt.Layer1.genesis_info; - kind; - block_finality_time = 2; - fee_parameters; - protocol_constants; - loser_mode; - store; - context; - } - -let checkout_context node_ctxt block_hash = - let open Lwt_result_syntax in - let*! context_hash = Store.Contexts.find node_ctxt.store block_hash in - let*? context_hash = - match context_hash with - | None -> - error (Sc_rollup_node_errors.Cannot_checkout_context (block_hash, None)) - | Some context_hash -> ok context_hash - in - let*! ctxt = Context.checkout node_ctxt.context context_hash in - match ctxt with - | None -> - tzfail - (Sc_rollup_node_errors.Cannot_checkout_context - (block_hash, Some (Context.hash_to_raw_string context_hash))) - | Some ctxt -> return ctxt diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/node_context.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/node_context.mli deleted file mode 100644 index 1402747429c5f2aa750dae9e29969815860ac3c3..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/node_context.mli +++ /dev/null @@ -1,97 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 describes the execution context of the node. *) - -open Protocol -open Alpha_context - -type t = { - cctxt : Protocol_client_context.full; - (** Client context used by the rollup node. *) - dal_cctxt : Dal_node_client.cctxt; - (** Client context to query the dal node. *) - data_dir : string; (** Node data dir. *) - l1_ctxt : Layer1.t; - (** Layer 1 context to fetch blocks and monitor heads, etc.*) - rollup_address : Sc_rollup.t; - (** Smart contract rollup tracked by the rollup node. *) - operators : Configuration.operators; - (** Addresses of the rollup node operators by purposes. *) - genesis_info : Sc_rollup.Commitment.genesis_info; - (** Origination information of the smart contract rollup. *) - block_finality_time : int; - (** Deterministic block finality time for the layer 1 protocol. *) - kind : Sc_rollup.Kind.t; (** Kind of the smart contract rollup. *) - fee_parameters : Configuration.fee_parameters; - (** Fee parameters to use when injecting operations in layer 1. *) - protocol_constants : Constants.t; - (** Protocol constants retrieved from the Tezos node. *) - loser_mode : Loser_mode.t; - (** If different from [Loser_mode.no_failures], the rollup node - issues wrong commitments (for tests). *) - store : Store.t; (** The store for the persistent storage. *) - context : Context.index; (** The persistent context for the rollup node. *) -} - -(** [get_operator cctxt purpose] returns the public key hash for the operator - who has purpose [purpose], if any. -*) -val get_operator : - t -> Configuration.purpose -> Signature.Public_key_hash.t option - -(** [is_operator cctxt pkh] returns [true] if the public key hash [pkh] is an - operator for the node (for any purpose). *) -val is_operator : t -> Signature.Public_key_hash.t -> bool - -(** [get_fee_parameter cctxt purpose] returns the fee parameter to inject an - operation for a given [purpose]. If no specific fee parameters were - configured for this purpose, returns the default fee parameter for this - purpose. -*) -val get_fee_parameter : t -> Configuration.purpose -> Injection.fee_parameter - -(** [init cctxt dal_cctxt ~data_dir l1_ctxt sc_rollup genesis_info kind operators fees - ~loser_mode store context] initialises the rollup representation. The rollup - origination level and kind are fetched via an RPC call to the layer1 node - that [cctxt] uses for RPC requests. -*) -val init : - Protocol_client_context.full -> - Dal_node_client.cctxt -> - data_dir:string -> - Layer1.t -> - Sc_rollup.t -> - Protocol.Alpha_context.Sc_rollup.Kind.t -> - Configuration.operators -> - Configuration.fee_parameters -> - loser_mode:Loser_mode.t -> - Store.t -> - Context.index -> - t tzresult Lwt.t - -(** [checkout_context node_ctxt block_hash] returns the context at block - [block_hash]. *) -val checkout_context : t -> Block_hash.t -> Context.t tzresult Lwt.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/outbox.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/outbox.ml deleted file mode 100644 index 29ae63ecceed535383ec24290ea40754c6a182d6..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/outbox.ml +++ /dev/null @@ -1,81 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 helper to interact with PVM outboxes. *) - -open Node_context -open Protocol.Alpha_context - -module Make (PVM : Pvm.S) = struct - let get_head store = - let open Lwt_result_syntax in - let*! head = Layer1.current_head_hash store in - match head with None -> failwith "No head" | Some head -> return head - - let get_context (node_ctxt : Node_context.t) = - let open Lwt_result_syntax in - let* head = get_head node_ctxt.store in - let* ctxt = Node_context.checkout_context node_ctxt head in - return ctxt - - let get_state_of_lcc node_ctxt = - let open Lwt_result_syntax in - let*! lcc_level = - Store.Last_cemented_commitment_level.get node_ctxt.store - in - let*! block_hash = - Layer1.hash_of_level node_ctxt.store (Raw_level.to_int32 lcc_level) - in - let* ctxt = Node_context.checkout_context node_ctxt block_hash in - let*! state = PVM.State.find ctxt in - return state - - let proof_of_output node_ctxt output = - let open Lwt_result_syntax in - let*! commitment_hash = - Store.Last_cemented_commitment_hash.get node_ctxt.store - in - let* state = get_state_of_lcc node_ctxt in - match state with - | None -> - (* - This case should never happen as origination creates an LCC which - must have been considered by the rollup node at startup time. - *) - failwith "Error producing outbox proof (no cemented state in the node)" - | Some state -> ( - let*! proof = PVM.produce_output_proof node_ctxt.context state output in - match proof with - | Ok proof -> - let serialized_proof = - Data_encoding.Binary.to_string_exn PVM.output_proof_encoding proof - in - return @@ (commitment_hash, serialized_proof) - | Error err -> - failwith - "Error producing outbox proof (%a)" - Environment.Error_monad.pp - err) -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/pvm.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/pvm.ml deleted file mode 100644 index 0fa214ff08f5e743440804d56f81aeda1a8f675d..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/pvm.ml +++ /dev/null @@ -1,67 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 - -(** Desired module type of a PVM from the L2 node's perspective *) -module type S = sig - include - Sc_rollup.PVM.S - with type context = Context.index - and type hash = Sc_rollup.State_hash.t - - (** [get_tick state] gets the total tick counter for the given PVM state. *) - val get_tick : state -> Sc_rollup.Tick.t Lwt.t - - (** PVM status *) - type status - - (** [get_status state] gives you the current execution status for the PVM. *) - val get_status : state -> status Lwt.t - - (** [string_of_status status] returns a string representation of [status]. *) - val string_of_status : status -> string - - (** [get_outbox state] returns a list of outputs available in the - outbox of [state]. *) - val get_outbox : state -> Sc_rollup.output list Lwt.t - - (** State storage for this PVM. *) - module State : sig - (** [find context] returns the PVM state stored in the [context], if any. *) - val find : Context.t -> state option Lwt.t - - (** [lookup state path] returns the data stored for the path [path] in the - PVM state [state]. *) - val lookup : state -> string list -> bytes option Lwt.t - - (** [set context state] saves the PVM state [state] in the context and - returns the updated context. Note: [set] does not perform any write on - disk, this information must be committed using {!Context.commit}. *) - val set : Context.t -> state -> Context.t Lwt.t - end -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/refutation_game.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/refutation_game.ml deleted file mode 100644 index 7468353aa1b207512cd46535a30e82d45ed9e873..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/refutation_game.ml +++ /dev/null @@ -1,345 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 refutation game logic of the rollup - node. - - When a new L1 block arises, the rollup node asks the L1 node for - the current game it is part of, if any. - - If a game is running and it is the rollup operator turn, the rollup - node injects the next move of the winning strategy. - - If a game is running and it is not the rollup operator turn, the - rollup node asks the L1 node whether the timeout is reached to play - the timeout argument if possible. - - Otherwise, if no game is running, the rollup node asks the L1 node - whether there is a conflict with one of its disputable commitments. If - there is such a conflict with a commitment C', then the rollup node - starts a game to refute C' by starting a game with one of its staker. - -*) -open Protocol - -open Alpha_context - -module type S = sig - module PVM : Pvm.S - - val process : - Layer1.head -> Configuration.t -> Node_context.t -> unit tzresult Lwt.t -end - -module Make (Interpreter : Interpreter.S) : - S with module PVM = Interpreter.PVM = struct - module PVM = Interpreter.PVM - open Sc_rollup.Game - - let node_role ~self Sc_rollup.Game.Index.{alice; bob} = - if Sc_rollup.Staker.equal alice self then Alice - else if Sc_rollup.Staker.equal bob self then Bob - else (* By validity of [ongoing_game] RPC. *) - assert false - - type role = Our_turn of {opponent : public_key_hash} | Their_turn - - let turn ~self game players = - let Sc_rollup.Game.Index.{alice; bob} = players in - match (node_role ~self players, game.turn) with - | Alice, Alice -> Our_turn {opponent = bob} - | Bob, Bob -> Our_turn {opponent = alice} - | Alice, Bob -> Their_turn - | Bob, Alice -> Their_turn - - (** [inject_next_move node_ctxt source ~refuation ~opponent] submits an L1 - operation (signed by [source]) to issue the next move in the refutation - game. *) - let inject_next_move (node_ctxt : Node_context.t) source ~refutation ~opponent - = - let refute_operation = - Sc_rollup_refute {rollup = node_ctxt.rollup_address; refutation; opponent} - in - Injector.add_pending_operation ~source refute_operation - - let generate_proof configuration node_ctxt game start_state = - let open Lwt_result_syntax in - let*! hash = - Layer1.hash_of_level - node_ctxt.Node_context.store - (Raw_level.to_int32 game.level) - in - let* history = Inbox.history_of_hash node_ctxt hash in - let* inbox = Inbox.inbox_of_hash node_ctxt hash in - let* ctxt = Node_context.checkout_context node_ctxt hash in - let*! messages_tree = Context.MessageTrees.find ctxt in - let* history, history_proof = - Context.Inbox.form_history_proof - node_ctxt.context - history - inbox - messages_tree - >|= Environment.wrap_tzresult - in - let module P = struct - include PVM - - let context = node_ctxt.context - - let state = start_state - - let reveal hash = - Reveals.get - ~data_dir:configuration.Configuration.data_dir - ~pvm_name:PVM.name - ~hash - - module Inbox_with_history = struct - include Context.Inbox - - let history = history - - let inbox = history_proof - end - end in - let* proof = - trace - (Sc_rollup_node_errors.Cannot_produce_proof (inbox, history, game.level)) - @@ (Sc_rollup.Proof.produce (module P) game.level - >|= Environment.wrap_tzresult) - in - let*! res = - Sc_rollup.Proof.valid - history_proof - game.level - ~pvm_name:game.pvm_name - proof - >|= Environment.wrap_tzresult - in - if Result.is_ok res then return proof else assert false - - let new_dissection ~default_number_of_sections node_ctxt last_level ok - our_view = - let state_hash_from_tick tick = - let open Lwt_result_syntax in - let* r = Interpreter.state_of_tick node_ctxt tick last_level in - return (Option.map snd r) - in - let start_hash, start_tick = ok in - let start_chunk = {state_hash = Some start_hash; tick = start_tick} in - let start_hash, start_tick = our_view in - let our_stop_chunk = {state_hash = start_hash; tick = start_tick} in - Game_helpers.new_dissection - ~start_chunk - ~our_stop_chunk - ~default_number_of_sections - ~state_hash_from_tick - - (** [generate_from_dissection ~default_number_of_sections node_ctxt game - dissection] traverses the current [dissection] and returns a move which - performs a new dissection of the execution trace or provides a refutation - proof to serve as the next move of the [game]. *) - let generate_next_dissection ~default_number_of_sections node_ctxt game - dissection = - let open Lwt_result_syntax in - let rec traverse ok = function - | [] -> - (* The game invariant states that the dissection from the - opponent must contain a tick we disagree with. If the - retrieved game does not respect this, we cannot trust the - Tezos node we are connected to and prefer to stop here. *) - tzfail - Sc_rollup_node_errors - .Unreliable_tezos_node_returning_inconsistent_game - | {state_hash = their_hash; tick} :: dissection -> ( - let open Lwt_result_syntax in - let* our = Interpreter.state_of_tick node_ctxt tick game.level in - match (their_hash, our) with - | None, None -> - (* This case is absurd since: [None] can only occur at the - end and the two players disagree about the end. *) - assert false - | Some _, None | None, Some _ -> - return (ok, (Option.map snd our, tick)) - | Some their_hash, Some (_, our_hash) -> - if Sc_rollup.State_hash.equal our_hash their_hash then - traverse (their_hash, tick) dissection - else return (ok, (Some our_hash, tick))) - in - match dissection with - | {state_hash = Some hash; tick} :: dissection -> - let* ok, ko = traverse (hash, tick) dissection in - let choice = snd ok in - let* dissection = - new_dissection ~default_number_of_sections node_ctxt game.level ok ko - in - let chosen_section_len = Sc_rollup.Tick.distance (snd ko) choice in - return (choice, chosen_section_len, dissection) - | [] | {state_hash = None; _} :: _ -> - (* - By wellformedness of dissection. - A dissection always starts with a tick of the form [(Some hash, tick)]. - A dissection always contains strictly more than one element. - *) - tzfail - Sc_rollup_node_errors - .Unreliable_tezos_node_returning_inconsistent_game - - let next_move configuration node_ctxt game = - let open Lwt_result_syntax in - let final_move start_tick = - let* start_state = - Interpreter.state_of_tick node_ctxt start_tick game.level - in - match start_state with - | None -> - tzfail - Sc_rollup_node_errors - .Unreliable_tezos_node_returning_inconsistent_game - | Some (start_state, _start_hash) -> - let* proof = - generate_proof configuration node_ctxt game start_state - in - let choice = start_tick in - return {choice; step = Proof proof} - in - - match game.game_state with - | Dissecting {dissection; default_number_of_sections} -> - let* choice, chosen_section_len, dissection = - generate_next_dissection - ~default_number_of_sections - node_ctxt - game - dissection - in - if Z.(equal chosen_section_len one) then final_move choice - else return {choice; step = Dissection dissection} - | Final_move {agreed_start_chunk; refuted_stop_chunk = _} -> - let choice = agreed_start_chunk.tick in - final_move choice - - let play_next_move configuration node_ctxt game self opponent = - let open Lwt_result_syntax in - let* refutation = next_move configuration node_ctxt game in - inject_next_move node_ctxt self ~refutation:(Some refutation) ~opponent - - let play_timeout (node_ctxt : Node_context.t) self stakers = - let timeout_operation = - Sc_rollup_timeout {rollup = node_ctxt.rollup_address; stakers} - in - let source = - Node_context.get_operator node_ctxt Timeout |> Option.value ~default:self - (* We fallback on the [Refute] operator if none is provided for [Timeout] *) - in - Injector.add_pending_operation ~source timeout_operation - - let timeout_reached ~self head_block node_ctxt players = - let open Lwt_result_syntax in - let Node_context.{rollup_address; cctxt; _} = node_ctxt in - let* game_result = - Plugin.RPC.Sc_rollup.timeout_reached - cctxt - (cctxt#chain, head_block) - rollup_address - players - () - in - let open Sc_rollup.Game in - match game_result with - | Some (Loser {loser; _}) -> - let is_it_me = Signature.Public_key_hash.(self = loser) in - return (not is_it_me) - | _ -> return_false - - let play head_block configuration node_ctxt self game staker1 staker2 = - let open Lwt_result_syntax in - let players = (staker1, staker2) in - let index = Sc_rollup.Game.Index.make staker1 staker2 in - match turn ~self game index with - | Our_turn {opponent} -> - play_next_move configuration node_ctxt game self opponent - | Their_turn -> - let* timeout_reached = - timeout_reached ~self head_block node_ctxt players - in - unless timeout_reached @@ fun () -> play_timeout node_ctxt self index - - let ongoing_game head_block node_ctxt self = - let Node_context.{rollup_address; cctxt; _} = node_ctxt in - Plugin.RPC.Sc_rollup.ongoing_refutation_game - cctxt - (cctxt#chain, head_block) - rollup_address - self - () - - let play_opening_move node_ctxt self conflict = - let open Lwt_syntax in - let open Sc_rollup.Refutation_storage in - let* () = Refutation_game_event.conflict_detected conflict in - inject_next_move node_ctxt self ~refutation:None ~opponent:conflict.other - - let start_game_if_conflict head_block node_ctxt self = - let open Lwt_result_syntax in - let Node_context.{rollup_address; cctxt; _} = node_ctxt in - let* conflicts = - Plugin.RPC.Sc_rollup.conflicts - cctxt - (cctxt#chain, head_block) - rollup_address - self - () - in - let*! res = - Option.iter_es (play_opening_move node_ctxt self) (List.hd conflicts) - in - match res with - | Ok r -> return r - | Error - [ - Environment.Ecoproto_error - Sc_rollup_errors.Sc_rollup_game_already_started; - ] -> - (* The game may already be starting in the meantime. So we - ignore this error. *) - return_unit - | Error errs -> Lwt.return (Error errs) - - let process (Layer1.Head {hash; _}) configuration node_ctxt = - let head_block = `Hash (hash, 0) in - let open Lwt_result_syntax in - let refute_signer = Node_context.get_operator node_ctxt Refute in - match refute_signer with - | None -> - (* Not injecting refutations, don't play refutation games *) - return_unit - | Some self -> ( - let* res = ongoing_game head_block node_ctxt self in - match res with - | Some (game, staker1, staker2) -> - play head_block configuration node_ctxt self game staker1 staker2 - | None -> start_game_if_conflict head_block node_ctxt self) -end diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/refutation_game.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/refutation_game.mli deleted file mode 100644 index 4902f42664d6544cbfe5f68a239ec9703da85f97..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/refutation_game.mli +++ /dev/null @@ -1,37 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 refutation game logic of the rollup - node. *) -module type S = sig - module PVM : Pvm.S - - (** [process head config node_ctxt] reacts to any operations of - [head] related to refutation games. *) - val process : - Layer1.head -> Configuration.t -> Node_context.t -> unit tzresult Lwt.t -end - -module Make (Interpreter : Interpreter.S) : S with module PVM = Interpreter.PVM diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/refutation_game_event.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/refutation_game_event.ml deleted file mode 100644 index b7b96030d0135b8978f8582e8be6bdf75ec08648..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/refutation_game_event.ml +++ /dev/null @@ -1,94 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2880 - Add corresponding .mli file. *) - -module Simple = struct - include Internal_event.Simple - - let section = ["sc_rollup_node"; "refutation_game"] - - let timeout = - declare_1 - ~section - ~name:"sc_rollup_node_timeout" - ~msg: - "The rollup node has been slashed because of a timeout issued by \ - {address}" - ~level:Notice - ("address", Signature.Public_key_hash.encoding) - - let invalid_move = - declare_0 - ~section - ~name:"sc_rollup_node_invalid_move" - ~msg: - "The rollup node is about to make an invalid move in the refutation \ - game! It is stopped to avoid being slashed. The problem should be \ - reported immediately or the rollup node should be upgraded to have a \ - chance to be back before the timeout is reached." - ~level:Notice - () - - let conflict_detected = - declare_5 - ~name:"sc_rollup_node_conflict_detected" - ~msg: - "A conflict has been found with our commitment {our_commitment_hash} \ - at level {level} with staker {other} that hash issued commitment \ - {their_commitment_hash} both based on {parent_commitment_hash}." - ~level:Notice - ("our_commitment_hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) - ("other", Sc_rollup.Staker.encoding) - ("their_commitment_hash", Sc_rollup.Commitment.Hash.encoding) - ("parent_commitment_hash", Sc_rollup.Commitment.Hash.encoding) -end - -let timeout address = Simple.(emit timeout address) - -let invalid_move () = Simple.(emit invalid_move ()) - -let conflict_detected (conflict : Sc_rollup.Refutation_storage.conflict) = - let our_commitment_hash = - Sc_rollup.Commitment.hash_uncarbonated conflict.our_commitment - in - let their_commitment_hash = - Sc_rollup.Commitment.hash_uncarbonated conflict.their_commitment - in - let parent_commitment_hash = conflict.parent_commitment in - let other = conflict.other in - let level = conflict.our_commitment.inbox_level in - Simple.( - emit - conflict_detected - ( our_commitment_hash, - level, - other, - their_commitment_hash, - parent_commitment_hash )) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/reveals.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/reveals.ml deleted file mode 100644 index 72ace672c7622c9e7403b03627f1c00fb9c51f2c..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/reveals.ml +++ /dev/null @@ -1,145 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 string_of_file filename = - let cin = open_in filename in - let s = really_input_string cin (in_channel_length cin) in - close_in cin ; - s - -let save_string filename s = - let cout = open_out filename in - output_string cout s ; - close_out cout - -let path data_dir pvm_name hash = - let hash = - Format.asprintf "%a" Protocol.Alpha_context.Sc_rollup.Input_hash.pp hash - in - Filename.(concat (concat data_dir pvm_name) hash) - -let ensure_dir_exists data_dir pvm_name = - let path = Filename.concat data_dir pvm_name in - if Sys.(file_exists path) then ( - if not (Sys.is_directory path) then - Stdlib.failwith (path ^ " should be a directory.")) - else Sys.mkdir path 0o700 - -let get ~data_dir ~pvm_name ~hash = - try Some (string_of_file (path data_dir pvm_name hash)) with _ -> None - -module Arith = struct - let pvm_name = - Protocol.Alpha_context.Sc_rollup.ArithPVM.Protocol_implementation.name - - let rev_chunks_of_file filename = - (* FIXME: https://gitlab.com/tezos/tezos/-/issues/3853 - Can be made more efficient. *) - let get_char cin = try Some (input_char cin) with End_of_file -> None in - let buf = Buffer.create 31 in - let tokens = - let cin = open_in filename in - let rec aux tokens = - match get_char cin with - | None -> - List.rev - @@ - if Buffer.length buf > 0 then - let token = Buffer.contents buf in - token :: tokens - else tokens - | Some ' ' -> - let token = Buffer.contents buf in - Buffer.clear buf ; - aux (token :: tokens) - | Some c -> - Buffer.add_char buf c ; - aux tokens - in - let tokens = aux [] in - close_in cin ; - tokens - in - let limit = - (4 * 1024) - 100 (* We reserve 100 bytes for the continuation hash. *) - in - Buffer.clear buf ; - let make_chunk () = - let chunk = Buffer.contents buf in - Buffer.clear buf ; - chunk - in - let chunks, _ = - List.fold_left - (fun (chunks, size) token -> - let len = String.length token in - if size + len > limit then ( - let chunk = make_chunk () in - Buffer.add_string buf token ; - (chunk :: chunks, len)) - else ( - if Buffer.length buf > 0 then Buffer.add_char buf ' ' ; - Buffer.add_string buf token ; - (chunks, size + len))) - ([], 0) - tokens - in - let chunks = - if Buffer.length buf > 0 then make_chunk () :: chunks else chunks - in - chunks - - let link_rev_chunks rev_chunks = - let rec aux successor_hash linked_chunks = function - | [] -> linked_chunks - | chunk :: rev_chunks -> - let open Protocol.Alpha_context.Sc_rollup in - let cell = - match successor_hash with - | None -> chunk - | Some h -> Format.asprintf "%s hash:%a" chunk Input_hash.pp h - in - let hash = Input_hash.hash_string [cell] in - aux (Some hash) ((cell, hash) :: linked_chunks) rev_chunks - in - aux None [] rev_chunks - - let import data_dir filename = - ensure_dir_exists data_dir pvm_name ; - let rev_chunks = rev_chunks_of_file filename in - let linked_hashed_chunks = link_rev_chunks rev_chunks in - List.iter - (fun (data, hash) -> save_string (path data_dir pvm_name hash) data) - linked_hashed_chunks ; - Stdlib.List.hd linked_hashed_chunks |> snd -end - -let import ~data_dir ~pvm_name ~filename = - if - String.equal - pvm_name - Protocol.Alpha_context.Sc_rollup.ArithPVM.Protocol_implementation.name - then Arith.import data_dir filename - else Stdlib.failwith "Not supported yet" diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/reveals.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/reveals.mli deleted file mode 100644 index 5cfe123ebc29a4dc55fabc0a965a505f20465212..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/reveals.mli +++ /dev/null @@ -1,69 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 basic support for reveals. - - The rollup can ask for data being the reveal of some hash. This - allows transferring data directly to the rollup without going - through the L1 inbox. - - Data length must be under 4KB to be refutable in a single L1 - operation. - - Data must be made available by off-chain mechanisms: it is the - responsibility of the rollup kernel to make sure that the reveal - data is available: otherwise, there is a potential safety issue. - - For the moment, the support is basic and mostly manual as the operator - needs to explicitly import a file in the rollup node data directoy to - enable the rollup node to answer reveal requests. - -*) - -(* FIXME:https://gitlab.com/tezos/tezos/-/issues/3854 - - We should probably have a mechanism to let the kernel declare - sources of reveal data so that the rollup node can automatically - download data in advance. *) - -open Protocol.Alpha_context - -(** [get ~data_dir ~pvm_name ~hash] returns [Some data] such that - [Input_hash.hash_string [data] = hash]. If such [data] is known - to the rollup node. Otherwise, returns [None]. *) -val get : - data_dir:string -> - pvm_name:string -> - hash:Sc_rollup.Input_hash.t -> - string option - -(** [import ~data_dir ~pvm_name ~filename] turns the content of ~filename - into a chunk of pages of (at most) 4KB, returning the hash of the first - chunk. *) -val import : - data_dir:string -> - pvm_name:string -> - filename:string -> - Sc_rollup.Input_hash.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/sc_rollup_node_errors.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/sc_rollup_node_errors.ml deleted file mode 100644 index ca4f4bb931bc4ea0c927d0242603cbb9a615eab0..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/sc_rollup_node_errors.ml +++ /dev/null @@ -1,254 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 tez_sym = "\xEA\x9C\xA9" - -type error += - | Cannot_produce_proof of - Sc_rollup.Inbox.t * Sc_rollup.Inbox.History.t * Raw_level.t - | Missing_mode_operators of {mode : string; missing_operators : string list} - | Bad_minimal_fees of string - | Commitment_predecessor_should_be_LCC of Sc_rollup.Commitment.t - | Unreliable_tezos_node_returning_inconsistent_game - | Inconsistent_inbox of { - layer1_inbox : Sc_rollup.Inbox.t; - inbox : Sc_rollup.Inbox.t; - } - | Missing_PVM_state of Block_hash.t * Raw_level.t - | Cannot_checkout_context of Block_hash.t * string option - | Cannot_retrieve_reveal of Sc_rollup.Input_hash.t - -type error += - | Lost_game of - public_key_hash * Protocol.Alpha_context.Sc_rollup.Game.reason * Tez.t - -let () = - register_error_kind - `Permanent - ~id:"bad_minimal_fees_arg" - ~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:"internal.commitment_should_be_next_to_lcc" - ~title: - "Internal error: The next commitment should have the LCC as predecessor" - ~description: - "Internal error: The next commitment should have the LCC as predecessor" - ~pp:(fun ppf commitment -> - Format.fprintf - ppf - "invalid commitment '%a'" - Sc_rollup.Commitment.pp - commitment) - Data_encoding.(obj1 (req "commitment" Sc_rollup.Commitment.encoding)) - (function - | Commitment_predecessor_should_be_LCC commitment -> Some commitment - | _ -> None) - (fun commitment -> Commitment_predecessor_should_be_LCC commitment) ; - - register_error_kind - `Permanent - ~id:"internal.unreliable_tezos_node" - ~title:"Internal error: Tezos node seems unreliable" - ~description: - "Internal error: The game invariant states that the dissection from the \ - opponent must contain a tick we disagree with. If the retrieved game \ - does not respect this, we cannot trust the Tezos node we are connected \ - to and prefer to stop here." - ~pp:(fun _ppf () -> ()) - Data_encoding.unit - (function - | Unreliable_tezos_node_returning_inconsistent_game -> Some () | _ -> None) - (fun () -> Unreliable_tezos_node_returning_inconsistent_game) ; - - register_error_kind - `Permanent - ~id:"internal.cannot_produce_proof" - ~title:"Internal error: rollup node cannot produce refutation proof" - ~description: - "The rollup node is in a state that prevents it from producing \ - refutation proofs." - ~pp:(fun ppf (inbox, history, level) -> - Format.fprintf - ppf - "cannot produce proof for inbox %a of level %a with history %a" - Sc_rollup.Inbox.pp - inbox - Raw_level.pp - level - Sc_rollup.Inbox.History.pp - history) - Data_encoding.( - obj3 - (req "inbox" Sc_rollup.Inbox.encoding) - (req "history" Sc_rollup.Inbox.History.encoding) - (req "level" Raw_level.encoding)) - (function - | Cannot_produce_proof (inbox, history, level) -> - Some (inbox, history, level) - | _ -> None) - (fun (inbox, history, level) -> - Cannot_produce_proof (inbox, history, level)) ; - - register_error_kind - ~id:"sc_rollup.node.missing_mode_operators" - ~title:"Missing operators for the chosen mode" - ~description:"Missing operators for the chosen mode." - ~pp:(fun ppf (mode, missing_operators) -> - Format.fprintf - ppf - "@[Missing operators %a for mode %s.@]" - (Format.pp_print_list - ~pp_sep:(fun ppf () -> Format.fprintf ppf ",@ ") - Format.pp_print_string) - missing_operators - mode) - `Permanent - Data_encoding.( - obj2 (req "mode" string) (req "missing_operators" (list string))) - (function - | Missing_mode_operators {mode; missing_operators} -> - Some (mode, missing_operators) - | _ -> None) - (fun (mode, missing_operators) -> - Missing_mode_operators {mode; missing_operators}) ; - - register_error_kind - ~id:"internal.inconsistent_inbox" - ~title:"Internal error: Rollup node has an inconsistent inbox" - ~description: - "The rollup node inbox should be the same as the layer 1 inbox." - ~pp:(fun ppf (layer1_inbox, inbox) -> - Format.fprintf - ppf - "@[Rollup inbox:@;%a@]@;should be equal to @[Layer1 inbox:@;%a@]" - Sc_rollup.Inbox.pp - inbox - Sc_rollup.Inbox.pp - layer1_inbox) - `Permanent - Data_encoding.( - obj2 - (req "layer1_inbox" Sc_rollup.Inbox.encoding) - (req "inbox" Sc_rollup.Inbox.encoding)) - (function - | Inconsistent_inbox {layer1_inbox; inbox} -> Some (layer1_inbox, inbox) - | _ -> None) - (fun (layer1_inbox, inbox) -> Inconsistent_inbox {layer1_inbox; inbox}) ; - - register_error_kind - `Permanent - ~id:"internal.missing_pvm_state" - ~title:"Internal error: Missing PVM state" - ~description:"The rollup node cannot retrieve the state of the PVM." - ~pp:(fun ppf (block, level) -> - Format.fprintf - ppf - "Cannot retrieve PVM state for block %a at level %a" - Block_hash.pp - block - Raw_level.pp - level) - Data_encoding.( - obj2 (req "block" Block_hash.encoding) (req "level" Raw_level.encoding)) - (function - | Missing_PVM_state (block, level) -> Some (block, level) | _ -> None) - (fun (block, level) -> Missing_PVM_state (block, level)) ; - - register_error_kind - `Permanent - ~id:"internal.cannot_checkout_context" - ~title:"Internal error: Cannot checkout context" - ~description: - "The rollup node cannot checkout the context registered for the block." - ~pp:(fun ppf (block, context_hash) -> - Format.fprintf - ppf - "The context %sfor block %a cannot be checkouted" - (Option.fold - ~none:"" - ~some:(fun c -> Hex.(show (of_string c))) - context_hash) - Block_hash.pp - block) - Data_encoding.( - obj2 - (req "block" Block_hash.encoding) - (opt "context" (conv Bytes.of_string Bytes.to_string bytes))) - (function - | Cannot_checkout_context (block, context) -> Some (block, context) - | _ -> None) - (fun (block, context) -> Cannot_checkout_context (block, context)) ; - - register_error_kind - `Permanent - ~id:"sc_rollup.node.lost_game" - ~title:"Lost refutation game" - ~description:"The rollup node lost a refutation game." - ~pp:(fun ppf (loser, reason, slashed) -> - Format.fprintf - ppf - "The rollup node lost the refutation game for operator %a and was \ - slashed %s%a, for reason: %a." - Signature.Public_key_hash.pp - loser - tez_sym - Tez.pp - slashed - Protocol.Alpha_context.Sc_rollup.Game.pp_reason - reason) - Data_encoding.( - obj3 - (req "loser" Signature.Public_key_hash.encoding) - (req "reason" Protocol.Alpha_context.Sc_rollup.Game.reason_encoding) - (req "slashed" Tez.encoding)) - (function - | Lost_game (loser, reason, slashed) -> Some (loser, reason, slashed) - | _ -> None) - (fun (loser, reason, slashed) -> Lost_game (loser, reason, slashed)) ; - - register_error_kind - `Permanent - ~id:"internal.cannot_retrieve_reveal" - ~title:"Internal error: Cannot retrieve reveal of hash" - ~description:"The rollup node cannot retrieve a reveal asked by the rollup." - ~pp:(fun ppf hash -> - Format.fprintf - ppf - "The node cannot retrieve a reveal for hash %a" - Sc_rollup.Input_hash.pp - hash) - Data_encoding.(obj1 (req "hash" Sc_rollup.Input_hash.encoding)) - (function Cannot_retrieve_reveal hash -> Some hash | _ -> None) - (fun hash -> Cannot_retrieve_reveal hash) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/store.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/store.ml deleted file mode 100644 index 7e9d48ca0260e258f2534060ec206ab588a90564..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/store.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 Protocol -include Store_utils - -(** Aggregated collection of messages from the L1 inbox *) -open Alpha_context - -type state_info = { - num_messages : Z.t; - num_ticks : Z.t; - initial_tick : Sc_rollup.Tick.t; -} - -(** Extraneous state information for the PVM *) -module StateInfo = Make_append_only_map (struct - let path = ["state_info"] - - let keep_last_n_entries_in_memory = 6000 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = state_info - - let value_encoding = - let open Data_encoding in - conv - (fun {num_messages; num_ticks; initial_tick} -> - (num_messages, num_ticks, initial_tick)) - (fun (num_messages, num_ticks, initial_tick) -> - {num_messages; num_ticks; initial_tick}) - (obj3 - (req "num_messages" Data_encoding.z) - (req "num_ticks" Data_encoding.z) - (req "initial_tick" Sc_rollup.Tick.encoding)) -end) - -module StateHistoryRepr = struct - let path = ["state_history"] - - type event = { - tick : Sc_rollup.Tick.t; - block_hash : Block_hash.t; - predecessor_hash : Block_hash.t; - level : Raw_level.t; - } - - module TickMap = Map.Make (Sc_rollup.Tick) - - type value = event TickMap.t - - let event_encoding = - let open Data_encoding in - conv - (fun {tick; block_hash; predecessor_hash; level} -> - (tick, block_hash, predecessor_hash, level)) - (fun (tick, block_hash, predecessor_hash, level) -> - {tick; block_hash; predecessor_hash; level}) - (obj4 - (req "tick" Sc_rollup.Tick.encoding) - (req "block_hash" Block_hash.encoding) - (req "predecessor_hash" Block_hash.encoding) - (req "level" Raw_level.encoding)) - - let value_encoding = - let open Data_encoding in - conv - TickMap.bindings - (fun bindings -> TickMap.of_seq (List.to_seq bindings)) - (Data_encoding.list (tup2 Sc_rollup.Tick.encoding event_encoding)) -end - -module StateHistory = struct - include Make_mutable_value (StateHistoryRepr) - - let insert store event = - let open Lwt_result_syntax in - let open StateHistoryRepr in - let*! history = find store in - let history = - match history with - | None -> StateHistoryRepr.TickMap.empty - | Some history -> history - in - set store (TickMap.add event.tick event history) - - let event_of_largest_tick_before store tick = - let open Lwt_result_syntax in - let open StateHistoryRepr in - let*! history = find store in - match history with - | None -> return_none - | Some history -> ( - let events_before, opt_value, _ = TickMap.split tick history in - match opt_value with - | Some event -> return (Some event) - | None -> - return @@ Option.map snd @@ TickMap.max_binding_opt events_before) -end - -(** Unaggregated messages per block *) -module Messages = Make_append_only_map (struct - let path = ["messages"] - - let keep_last_n_entries_in_memory = 10 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = Sc_rollup.Inbox_message.t list - - let value_encoding = - Data_encoding.(list @@ dynamic_size Sc_rollup.Inbox_message.encoding) -end) - -(** Inbox state for each block *) -module Inboxes = Make_append_only_map (struct - let path = ["inboxes"] - - let keep_last_n_entries_in_memory = 10 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = Sc_rollup.Inbox.t - - let value_encoding = Sc_rollup.Inbox.encoding -end) - -(** Message history for the inbox at a given block *) -module Histories = Make_append_only_map (struct - let path = ["histories"] - - let keep_last_n_entries_in_memory = 10 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = Sc_rollup.Inbox.History.t - - let value_encoding = Sc_rollup.Inbox.History.encoding -end) - -module Commitments = Make_append_only_map (struct - let path = ["commitments"; "computed"] - - let keep_last_n_entries_in_memory = 10 - - type key = Raw_level.t - - let string_of_key l = Int32.to_string @@ Raw_level.to_int32 l - - type value = Sc_rollup.Commitment.t * Sc_rollup.Commitment.Hash.t - - let value_encoding = - Data_encoding.( - obj2 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding)) -end) - -module Last_stored_commitment_level = Make_mutable_value (struct - let path = ["commitments"; "last_stored_level"] - - type value = Raw_level.t - - let value_encoding = Raw_level.encoding -end) - -module Last_published_commitment_level = Make_mutable_value (struct - let path = ["commitments"; "last_published_level"] - - type value = Raw_level.t - - let value_encoding = Raw_level.encoding -end) - -module Last_cemented_commitment_level = Make_mutable_value (struct - let path = ["commitments"; "last_cemented_commitment"; "level"] - - type value = Raw_level.t - - let value_encoding = Raw_level.encoding -end) - -module Last_cemented_commitment_hash = Make_mutable_value (struct - let path = ["commitments"; "last_cemented_commitment"; "hash"] - - type value = Sc_rollup.Commitment.Hash.t - - let value_encoding = Sc_rollup.Commitment.Hash.encoding -end) - -module Commitments_published_at_level = Make_updatable_map (struct - let path = ["commitments"; "published_at_level"] - - let keep_last_n_entries_in_memory = 10 - - type key = Sc_rollup.Commitment.Hash.t - - let string_of_key = Sc_rollup.Commitment.Hash.to_b58check - - type value = Raw_level.t - - let value_encoding = Raw_level.encoding -end) - -(* Slot subscriptions per block hash, saved as a list of - `Dal.Slot_index.t`, which is a bounded integer between `0` and `255` - included. *) -module Dal_slot_subscriptions = Make_append_only_map (struct - let path = ["dal"; "slot_subscriptions"] - - let keep_last_n_entries_in_memory = 10 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = Dal.Slot_index.t list - - let value_encoding = Data_encoding.list Dal.Slot_index.encoding -end) - -module Contexts = Make_append_only_map (struct - let path = ["contexts"] - - let keep_last_n_entries_in_memory = 10 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = Context.hash - - let value_encoding = Context.hash_encoding -end) - -module Block_slot_map_parameter = struct - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type secondary_key = Dal.Slot_index.t - - let compare_secondary_keys = Dal.Slot_index.compare - - type value = Dal.Slot.t - - let secondary_key_encoding = Dal.Slot_index.encoding - - let secondary_key_name = "slot_index" - - let value_encoding = Dal.Slot.encoding - - let value_name = "slots_metadata" -end - -(* Published slot headers per block hash, - stored as a list of bindings from `Dal_slot_index.t` - to `Dal.Slot.t`. The encoding function converts this - list into a `Dal.Slot_index.t`-indexed map. *) -module Dal_slots = Make_nested_map (struct - let path = ["dal"; "slot_headers"] - - (* FIXME/DAL: https://gitlab.com/tezos/tezos/-/issues/3527 - This value is currently not used, but required by the module type. *) - let keep_last_n_entries_in_memory = 10 - - include Block_slot_map_parameter -end) - -(* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/3515 - temporary - this is used for test purposes only. - Remove this piece of storage once we download blocks from the dal node. -*) -(* Published slot headers per block hash, stored as a list of bindings from - `Dal_slot_index.t` to `Dal.Slot.t`. The encoding function converts this - list into a `Dal.Slot_index.t`-indexed map. Note that the block_hash - refers to the block where slots headers have been confirmed, not - the block where they have been published. -*) -module Dal_confirmed_slots = Make_nested_map (struct - let path = ["dal"; "confirmed_slots"] - - (* FIXME/DAL: https://gitlab.com/tezos/tezos/-/issues/3527 - This value is currently not used, but required by the module type. *) - let keep_last_n_entries_in_memory = 10 - - include Block_slot_map_parameter -end) - -(** Confirmed DAL slots history. See documentation of - {Dal_slot_repr.Slots_history} for more details. *) -module Dal_confirmed_slots_history = Make_append_only_map (struct - let path = ["dal"; "confirmed_slots_history"] - - let keep_last_n_entries_in_memory = 10 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = Dal.Slots_history.t - - let value_encoding = Dal.Slots_history.encoding -end) - -(** Confirmed DAL slots histories cache. See documentation of - {Dal_slot_repr.Slots_history} for more details. *) -module Dal_confirmed_slots_histories = Make_append_only_map (struct - let path = ["dal"; "confirmed_slots_histories_cache"] - - let keep_last_n_entries_in_memory = 10 - - type key = Block_hash.t - - let string_of_key = Block_hash.to_b58check - - type value = Dal.Slots_history.History_cache.t - - let value_encoding = Dal.Slots_history.History_cache.encoding -end) diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/store.mli b/src/proto_015_PtLimaPt/bin_sc_rollup_node/store.mli deleted file mode 100644 index ace53b7e07abad8cfa5a1c96036b37c89fa761df..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/store.mli +++ /dev/null @@ -1,177 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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/3471 - Use indexed file for append-only instead of Irmin. *) - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/3739 - Refactor the store file to have functors in their own - separate module, and return errors within the Error monad. *) - -open Protocol -open Alpha_context - -type t = Store_utils.t - -type state_info = { - num_messages : Z.t; - num_ticks : Z.t; - initial_tick : Sc_rollup.Tick.t; -} - -(** Extraneous state information for the PVM *) -module StateInfo : - Store_utils.Map with type key = Block_hash.t and type value = state_info - -module StateHistoryRepr : sig - type event = { - tick : Sc_rollup.Tick.t; - block_hash : Block_hash.t; - predecessor_hash : Block_hash.t; - level : Raw_level.t; - } - - module TickMap : Map.S with type key = Sc_rollup.Tick.t - - type value = event TickMap.t -end - -(** [StateHistory] represents storage for the PVM state history: it is an - extension of [Store_utils.Mutable_value] whose values are lists of bindings - indexed by PVM tick numbers, and whose value contains information about the - block that the PVM was processing when generating the tick. -*) -module StateHistory : sig - include Store_utils.Mutable_value with type value = StateHistoryRepr.value - - val insert : t -> StateHistoryRepr.event -> unit Lwt.t - - val event_of_largest_tick_before : - t -> - StateHistoryRepr.TickMap.key -> - StateHistoryRepr.event option tzresult Lwt.t -end - -(** Storage for persisting messages downloaded from the L1 node, indexed by - [Block_hash.t]. *) -module Messages : - Store_utils.Map - with type key = Block_hash.t - and type value = Sc_rollup.Inbox_message.t list - -(** Aggregated collection of messages from the L1 inbox *) -module Inboxes : - Store_utils.Map - with type key = Block_hash.t - and type value = Sc_rollup.Inbox.t - -(** Histories from the rollup node. **) -module Histories : - Store_utils.Map - with type key = Block_hash.t - and type value = Sc_rollup.Inbox.History.t - -(** Storage containing commitments and corresponding commitment hashes that the - rollup node has knowledge of. *) -module Commitments : - Store_utils.Map - with type key = Raw_level.t - and type value = Sc_rollup.Commitment.t * Sc_rollup.Commitment.Hash.t - -(** Storage containing the inbox level of the last commitment produced by the - rollup node. *) -module Last_stored_commitment_level : - Store_utils.Mutable_value with type value = Raw_level.t - -(** Storage contianing the inbox level of the last commitment published by the - rollup node. *) -module Last_published_commitment_level : - Store_utils.Mutable_value with type value = Raw_level.t - -(** Storage containing the inbox level of the last commitment cemented for the - rollup. The commitment has not been necessarily generated by this rollup - node. *) -module Last_cemented_commitment_level : - Store_utils.Mutable_value with type value = Raw_level.t - -(** torage containing the hash of the last commitment cemented for the rollup. - The commitment has not been necessarily generated by this rollup node. *) -module Last_cemented_commitment_hash : - Store_utils.Mutable_value with type value = Sc_rollup.Commitment.Hash.t - -(** Storage mapping commitment hashes to the level when they were published by - the rollup node. It only contains hashes of commitments published by this - rollup node. *) -module Commitments_published_at_level : - Store_utils.Map - with type key = Sc_rollup.Commitment.Hash.t - and type value = Raw_level.t - -(** Storage containing the a [Block_hash.t]-indexed map whose values are - the slots to which the rollup was subscribed w.r.t. a block hash. *) -module Dal_slot_subscriptions : - Store_utils.Map - with type key = Block_hash.t - and type value = Dal.Slot_index.t list - -(** Storage containing the hashes of contexts retrieved from the L1 node. *) -module Contexts : - Store_utils.Map with type key = Block_hash.t and type value = Context.hash - -(** Published slot headers per block hash, - stored as a list of bindings from [Dal_slot_index.t] - to [Dal.Slot.t]. The encoding function converts this - list into a [Dal.Slot_index.t]-indexed map. *) -module Dal_slots : - Store_utils.Nested_map - with type primary_key = Block_hash.t - and type secondary_key = Dal.Slot_index.t - and type value = Dal.Slot.t - -(** Confirmed slot headers per block hash, stored as a list of bindings from - [Dal_slot_index.t] to [Dal.Slot.t]. The encoding function converts this - list into a [Dal.Slot_index.t]-indexed map. Note that the block_hash - refers to the block where slots headers have been confirmed, not - the block where they have been published. -*) -module Dal_confirmed_slots : - Store_utils.Nested_map - with type primary_key = Block_hash.t - and type secondary_key = Dal.Slot_index.t - and type value = Dal.Slot.t - -(** Confirmed DAL slots history. See documentation of - {Dal_slot_repr.Slots_history} for more details. *) -module Dal_confirmed_slots_history : - Store_utils.Map - with type key = Block_hash.t - and type value = Dal.Slots_history.t - -(** Confirmed DAL slots histories cache. See documentation of - {Dal_slot_repr.Slots_history} for more details. *) -module Dal_confirmed_slots_histories : - Store_utils.Map - with type key = Block_hash.t - and type value = Dal.Slots_history.History_cache.t diff --git a/src/proto_015_PtLimaPt/bin_sc_rollup_node/wasm_2_0_0_pvm.ml b/src/proto_015_PtLimaPt/bin_sc_rollup_node/wasm_2_0_0_pvm.ml deleted file mode 100644 index 3c2be05fa1e9c16a728f12fd8e3040edd96d0cd5..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/bin_sc_rollup_node/wasm_2_0_0_pvm.ml +++ /dev/null @@ -1,93 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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 manifests the proof format used by the Wasm PVM as defined by - the Layer 1 implementation for it. - - It is imperative that this is aligned with the protocol's implementation. -*) -module Wasm_2_0_0_proof_format = - Context.Proof - (struct - include Sc_rollup.State_hash - - let of_context_hash = Sc_rollup.State_hash.context_hash_to_state_hash - end) - (struct - let proof_encoding = - Tezos_context_merkle_proof_encoding.Merkle_proof_encoding.V2.Tree32 - .tree_proof_encoding - end) - -module type TreeS = - Tezos_context_sigs.Context.TREE - with type key = string list - and type value = bytes - -module Make_backend (Tree : TreeS) = struct - type Tezos_lazy_containers.Lazy_map.tree += PVM_tree of Tree.tree - - include Tezos_scoru_wasm.Wasm_pvm.Make (struct - include Tree - - let select = function - | PVM_tree t -> t - | _ -> raise Tezos_tree_encoding.Incorrect_tree_type - - let wrap t = PVM_tree t - end) - - (* We need to deal with the introduction of new constructors post V7 - freeze. *) - let get_info tree = - let open Lwt_syntax in - let+ Tezos_scoru_wasm.Wasm_pvm_sig. - {current_tick; last_input_read; input_request} = - get_info tree - in - Environment.Wasm_2_0_0. - { - current_tick; - last_input_read; - input_request = - (match input_request with - | Reveal_required _ | No_input_required -> No_input_required - | Input_required -> Input_required); - } -end - -module Impl : Pvm.S = struct - include Sc_rollup.Wasm_2_0_0PVM.Make (Make_backend) (Wasm_2_0_0_proof_format) - module State = Context.PVMState - - let string_of_status : status -> string = function - | Waiting_for_input_message -> "Waiting for input message" - | Computing -> "Computing" -end - -include Impl diff --git a/src/proto_015_PtLimaPt/lib_dal/dal_plugin_registration.ml b/src/proto_015_PtLimaPt/lib_dal/dal_plugin_registration.ml deleted file mode 100644 index ebcf861ab3125db04ed9a6046d94fa2121a84ff8..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_dal/dal_plugin_registration.ml +++ /dev/null @@ -1,63 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION 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 - - let get_constants chain block ctxt = - let cpctxt = new Protocol_client_context.wrap_full ctxt in - let open Lwt_result_syntax in - let* constants = Protocol.Constants_services.all cpctxt (chain, block) in - let Protocol.Alpha_context.Constants.Parametric. - {redundancy_factor; page_size; slot_size; number_of_shards; _} = - constants.parametric.dal - in - return - Environment.Dal. - {redundancy_factor; page_size; slot_size; number_of_shards} - - let get_published_slot_headers block ctxt = - let open Lwt_result_syntax in - let open Protocol.Alpha_context in - let cpctxt = new Protocol_client_context.wrap_full ctxt in - let* block = - Protocol_client_context.Alpha_block_services.info - cpctxt - ~block - ~metadata:`Always - () - in - let apply_internal acc ~source:_ _op _res = acc in - let apply (type kind) acc ~source:_ (op : kind manager_operation) _res = - match op with Dal_publish_slot_header {slot} -> slot :: acc | _ -> acc - in - Layer1_services.( - process_manager_operations [] block.operations {apply; apply_internal}) - |> List.map_es (fun slot -> - return - (Dal.Slot_index.to_int slot.Dal.Slot.id.index, slot.Dal.Slot.header)) -end - -let () = Dal_plugin.register (module Plugin) diff --git a/src/proto_015_PtLimaPt/lib_dal/dal_slot_frame_encoding.ml b/src/proto_015_PtLimaPt/lib_dal/dal_slot_frame_encoding.ml deleted file mode 100644 index f89360351623062b4fdb4075f09d1a987da14a75..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_dal/dal_slot_frame_encoding.ml +++ /dev/null @@ -1,257 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 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 Protocol -open Alpha_context -open Protocol_client_context - -type error += - | Slot_size_is_too_big of {actual_size : int; max_size : int} - | Wrong_slot_frame_version of {expected : int; provided : int} - | Could_not_deserialize_slot - -let () = - register_error_kind - `Permanent - ~id:"slot_size_is_too_big" - ~title:"Slot size is too big" - ~description:"Slot cannot fit in maximum size" - ~pp:(fun ppf (actual_size, max_size) -> - Format.fprintf - ppf - "Actual size: %d, Maximum size: %d" - actual_size - max_size) - Data_encoding.(obj2 (req "actual_size" int31) (req "maximum_size" int31)) - (function - | Slot_size_is_too_big {actual_size; max_size} -> - Some (actual_size, max_size) - | _ -> None) - (fun (actual_size, max_size) -> - Slot_size_is_too_big {actual_size; max_size}) ; - register_error_kind - `Permanent - ~id:"wrong_slot_frame_version" - ~title:"Wrong slot frame version" - ~description:"Wrong slot frame version" - ~pp:(fun ppf (expected, provided) -> - Format.fprintf - ppf - "Version expected: %d, Version provided: %d" - expected - provided) - Data_encoding.( - obj2 (req "version_expected" uint8) (req "version_provided" uint8)) - (function - | Wrong_slot_frame_version {expected; provided} -> - Some (expected, provided) - | _ -> None) - (fun (expected, provided) -> Wrong_slot_frame_version {expected; provided}) ; - register_error_kind - `Permanent - ~id:"could_not_deserialize_slot" - ~title:"Slot could not be deserialized" - ~description:"Error when recovering slot contents from binary" - ~pp:(fun ppf () -> - Format.fprintf ppf "Error when recovering slot contents from binary") - Data_encoding.(unit) - (function Could_not_deserialize_slot -> Some () | _ -> None) - (fun () -> Could_not_deserialize_slot) - -type version = int - -type message = string - -module Rollups_map = Map.Make (Sc_rollup.Address) - -type t = message list Rollups_map.t - -module type Slot_version = sig - val version_prefix : version - - val expected_slot_size : t -> int - - val serialize : max_size:int -> t -> string tzresult Lwt.t - - val deserialize : max_size:int -> string -> t tzresult Lwt.t -end - -let version_encoding = Data_encoding.uint8 - -module V0 = struct - let version_prefix = 0 - - (* Binary representation of string uses 4 bytes as a header, - containing the string length. This conforms to the specification - given for messages. *) - let message_encoding = Data_encoding.string - - (* Binary representation of lists uses 4 bytes as a header, containing - the length of the list in bytes. This conforms to the - specification given for messages frames. *) - let messages_frame_encoding = Data_encoding.(list message_encoding) - - (* Binary representation of lists uses 4 bytes as a header, containing - the size of the encoded list contents in bytes. - `all_messages_frame_encoding` encodes not only the encoded messages - frames, but also the 4 bytes containing the length of all messages - frames that separate the rollups frame from the messages frame. - *) - let all_messages_frames_encoding = - Data_encoding.(list messages_frame_encoding) - - (* Binary representation of a [Sc_rollup.Address.t] uses 20 bytes, - while the encoding of a [int32] uses 4 bytes. These are - concatenated together by `rollup_offset_entry_encoding`. *) - let rollup_offset_entry_encoding = - Data_encoding.(tup2 Sc_rollup.Address.encoding int32) - - (* Binary representation of lists uses 4 bytes as a header, containing - the size of the encoded list contents in bytes. - the size in bytes of the rollups frame. containing - the length of the list in bytes. Thus the rollups_frame_encoding - conforms to the specification given*) - let rollups_frame_encoding = Data_encoding.(list rollup_offset_entry_encoding) - - let slot_encoding ~max_size = - Data_encoding.( - check_size max_size - @@ tup3 - version_encoding - rollups_frame_encoding - all_messages_frames_encoding) - - module Internal = struct - let size_of_opt size = match size with None -> assert false | Some n -> n - - let message_size = Data_encoding.Binary.length message_encoding - - let messages_frame_size = - Data_encoding.Binary.length messages_frame_encoding - - let all_messages_frames_size = - Data_encoding.Binary.length all_messages_frames_encoding - - let frame_prefix_size = - size_of_opt Data_encoding.(Binary.fixed_length int32) - - let frame_version_size = - size_of_opt Data_encoding.(Binary.fixed_length uint8) - - let rollup_entry_size = - size_of_opt - @@ Data_encoding.Binary.fixed_length rollup_offset_entry_encoding - - let rollups_frame_size number_of_rollups = - (rollup_entry_size * number_of_rollups) + frame_prefix_size - end - - let expected_slot_size all_rollups_messages = - let bindings = Rollups_map.bindings all_rollups_messages in - let number_of_rollups = bindings |> List.length in - let messages = List.map snd bindings in - Internal.( - frame_version_size - + rollups_frame_size number_of_rollups - + all_messages_frames_size messages) - - let serialize ~max_size all_rollups_messages = - let open Lwt_result_syntax in - let first_messages_frame_offset = - Internal.( - frame_version_size - + rollups_frame_size - (Rollups_map.bindings all_rollups_messages |> List.length) - + frame_prefix_size) - in - let rev_rollups_frame, rev_messages_frames, expected_slot_size = - Rollups_map.fold - (fun rollup messages (rollups_frame, messages_frames, next_offset) -> - let rollups_frame = - (rollup, Int32.of_int next_offset) :: rollups_frame - in - let messages_frames = messages :: messages_frames in - let next_offset = - next_offset + Internal.messages_frame_size messages - in - (rollups_frame, messages_frames, next_offset)) - all_rollups_messages - ([], [], first_messages_frame_offset) - in - let* () = - fail_unless - (expected_slot_size <= max_size) - (Slot_size_is_too_big {actual_size = expected_slot_size; max_size}) - in - let rollups_frame = List.rev rev_rollups_frame in - let messages_frames = List.rev rev_messages_frames in - let*? result = - Data_encoding.Binary.to_string - (slot_encoding ~max_size) - (version_prefix, rollups_frame, messages_frames) - |> Result.map_error (fun _ -> assert false) - in - return result - - (* Deserialization of slot contents will be done by WASM PVM kernels, as - per #3374. However, we should still provide a function to - deserialize the contents of a slot, as other components other than the - PVM kernel may need to inspect it. *) - let deserialize ~max_size serialized = - let open Lwt_result_syntax in - let actual_size = String.length serialized in - let* () = - fail_unless - (actual_size <= max_size) - (Slot_size_is_too_big {actual_size; max_size}) - in - let version_prefix, rollups_frame, messages_frames = - Data_encoding.Binary.of_string_exn (slot_encoding ~max_size) serialized - in - let* () = - fail_when - (version_prefix <> 0) - (Wrong_slot_frame_version {expected = 0; provided = version_prefix}) - in - let* () = - fail_when - (List.compare_length_with messages_frames @@ List.length rollups_frame - <> 0) - Could_not_deserialize_slot - in - let*? deserialized = - List.map2 - ~when_different_lengths:[] - (fun (rollup, _offset) messages -> (rollup, messages)) - rollups_frame - messages_frames - |> Result.map_error (fun _ -> [Could_not_deserialize_slot]) - |> Result.map (fun rollups_with_messages -> - Rollups_map.add_seq - (List.to_seq rollups_with_messages) - Rollups_map.empty) - in - return deserialized -end diff --git a/src/proto_015_PtLimaPt/lib_dal/dal_slot_frame_encoding.mli b/src/proto_015_PtLimaPt/lib_dal/dal_slot_frame_encoding.mli deleted file mode 100644 index 2b6134c2b089c9dfb7978e6f8f97929f57b367bf..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_dal/dal_slot_frame_encoding.mli +++ /dev/null @@ -1,182 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 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. *) -(* *) -(*****************************************************************************) - -(* Library for encoding messages from distinct rollups into a slot. This - library contains encoding and decoding functions for different versions of - the slot-frame encoding. Currently, only one version, V0, exists. As the - structure of slot-frame progresses, new versions will be added. *) - -open Protocol -open Alpha_context - -type error += - | Slot_size_is_too_big of {actual_size : int; max_size : int} - | Wrong_slot_frame_version of {expected : int; provided : int} - | Could_not_deserialize_slot - -type version = int - -module Rollups_map : Map.S with type key = Sc_rollup.Address.t - -type message = string - -(* The type that will be used to serialize and deserialize a slot into a - slot-frame. It consists of a map from rollup addresses to list of - messages. *) -type t = message list Rollups_map.t - -(* Common interface for all slot versions. *) -module type Slot_version = sig - (* [version_prefix] denotes the version of the slot-frame encoding. - It must be a value between 0 and 255, and two different slot-frame - econdings cannot have the same version prefix. *) - val version_prefix : version - - (* [expected_slot_size rollups_messages] returns the value of the - size (in bytes) of a slot-frame that includes all the messages - in [rollups_messages]. It must satisfy the following property: - `expected_slot_size rollups_messages = - String.length @@ serialize rollups_messages`. - *) - val expected_slot_size : t -> int - - (* [serialize ~max_size rollups_messages] returns the encoding - of [rollups_messages] as a string, provided that the result - does not occupy more then [~max_size] byted. - When it succeeds, it must satisfy the following property: - `deserialize ~max_size @@ serialize ~max_size rollups_messages = - rollups_messages` - - May fail with: - {ul - {li [Slot_size_is_too_big {actual_size; max_size}] if the encoding of the - slot would take [actual_size] bytes, where `actual_size > max_size`} - } - *) - val serialize : max_size:int -> t -> string tzresult Lwt.t - - (* [deserialize ~max_size slot_frame] returns the rollup-address indexed map - of messages whose encoding corresponds to [slot_frame], as long as the - [slot_frame] does not occupy more then [~max_size] bytes, and [slot_frame] - contains the correct version_prefix, i.e. the first byte [slot_frame] - is set to `\000`. When it succeeds, it must satisfy the following property: - `serialize ~max_size @@ deserialize ~max_size slot_frame = - slot_frame` - - May fail with: - {ul - {li [Slot_size_is_too_big {actual_size; max_size}] if - [String.length slot_frame = actual_size], where - `actual_size > max_size`. - } - {li [Wrong_slot_frame_version of {expected; provided = 0}] if the first - byte of [slot_frame] is set to the binary encoding of [expected]. - } - {li [Could_not_deserialize_slot] if [slot_frame] does not correspond to - the serialization of a valid rollup-address indexed map of messages. - } - } - *) - val deserialize : max_size:int -> string -> t tzresult Lwt.t -end - -(*'V0' version of the slot-frame encoding. - Suppose that we want to include messages from rollups `r_1, ..., r_n`. - Specifically, for `i=1, ..., n`, suppose that rollup `r_i` wants to include - an arbitrary number j of messages `[m_{i,1}; ... m_{i, j} ]` into the slot. - The number of messages j to be included in a slot may be different for each - rollup. The encoded slot will consist of a string where: - {ul - {li The first byte contains the slot-frame version, currently set to `0x00`,} - {li The next `n * 24 + 4` bytes contain the `rollups-frame`, which contains - the information about where the messages for the rollups - `r_1, .., r_n` are stored. Specifically, the first 4 bytes denote the - length (in bytes) of the remaining part of the rollups-frame, which is - `n * 24`. This is followed by `n` entries of `24` bytes each. For each - entry, the first `20` bytes contain the encoded address of the rollup - node, while the other `4` contain the offset - from the start of the - slot - to the start of the rollup's messages-frame (described next). - } - {li The `4` bytes following the rollups frame contain the length of the - rest of the encoded slot, } - {li Next, there are n messages-frames, one for each rollup. For - `i = 1, ..., n`, the size of the i-th messages-frame is - `4 * n_i + (\sum_{j=1}^{n_i} |m_{i, j}|) + 4` bytes. The first four - bytes denote the length of the messages-frame. Then we have the - sequence of the encoded messages `m_{i,1}, ..., m_{i, j}`. The encoded - message `m_{i,j}` consists of 4 bytes representing `|m_{i,j}|`, - followed by `m_{i,j}` itself. - } - } - - As an example, suppose that we have two rollups `r1` and `r2`. For - simplicity, let's assume that the binary represenation of `r1` and `r2` are - `ROLLUP_ADDRESS_1XXXX` and `ROLLUP_ADDRESS_2YYYY`. Suppose that we want to - include in the slot messages [["hello"; "world"]] from `r1`, and messages - [["CAFEBABE"; "CAFEDEAD"]] from `r2` (in this order). The overall encoded - frame will be - "\000 - \000\000\000\048 - ROLLUP_ADDRESS_1XXXX\000\000\000\057 - ROLLUP_ADDRESS_2YYYY\000\000\000\079 - \000\000\000\050 - \000\000\000\018\000\000\000\005hello\000\000\000\005world - \000\000\000\024\000\000\000\008CAFEBABE\000\000\000\008CAFEDEAD". -*) -module V0 : sig - include Slot_version - - (* Functions used internally by the V0 version of the slot. These functions - are exposed so that they can be used in tests. This is necessary as we - will have implementations of the deserialization for the slot functions in - different programming languages. Checking the values returned by these - functions in tests will serve as documentation for developers wanting to - implement their own version of the V0 slot-frame deserialization. *) - module Internal : sig - (* [messages_size message] returns the size in bytes that [message] - would take in a slot-frame. *) - val message_size : message -> int - - (* [messages_frame_size messages] returns the size in bytes that the - encoding of messages as a messages frame would take in a slot-frame. *) - val messages_frame_size : message list -> int - - (* [all_messages_frame all_messages] returns the size in bytes - that the encoding of [all_messages] would take in a slot-frame. - This value includes the 4 bytes that separate the rollups-frame - from the rest of the slot frame in the encoding. *) - val all_messages_frames_size : message list list -> int - - (* [rollup_entry_size] returns the size in bytes - that one rollup would take in the rollups-frame. - *) - val rollup_entry_size : int - - (* [rollups_frame_size number_of_rollups] returns the size - in bytes that the rollups-frame would take in a slot-frame, - if the latter contains messages for [number_of_rollups] rollups. *) - val rollups_frame_size : int -> int - end -end diff --git a/src/proto_015_PtLimaPt/lib_dal/dune b/src/proto_015_PtLimaPt/lib_dal/dune deleted file mode 100644 index b06fdbb07d491be325032efca001ca6bf47d84a0..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_dal/dune +++ /dev/null @@ -1,28 +0,0 @@ -; This file was automatically generated, do not edit. -; Edit file manifest/main.ml instead. - -(library - (name tezos_dal_015_PtLimaPt) - (public_name tezos-dal-015-PtLimaPt) - (instrumentation (backend bisect_ppx)) - (libraries - tezos-base - octez-protocol-compiler.registerer - tezos_dal_node_lib - tezos-client-015-PtLimaPt - tezos-embedded-protocol-015-PtLimaPt - tezos-layer2-utils-015-PtLimaPt - tezos-protocol-015-PtLimaPt) - (inline_tests (flags -verbose) (modes native)) - (preprocess (pps ppx_expect)) - (library_flags (:standard -linkall)) - (flags - (:standard) - -open Tezos_base.TzPervasives - -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals - -open Tezos_protocol_registerer - -open Tezos_dal_node_lib - -open Tezos_client_015_PtLimaPt - -open Tezos_embedded_protocol_015_PtLimaPt - -open Tezos_layer2_utils_015_PtLimaPt - -open Tezos_protocol_015_PtLimaPt)) diff --git a/src/proto_015_PtLimaPt/lib_dal/test/dune b/src/proto_015_PtLimaPt/lib_dal/test/dune deleted file mode 100644 index e8bd31829cc00aa5a6aa92056fd29f2c860a6735..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_dal/test/dune +++ /dev/null @@ -1,25 +0,0 @@ -; This file was automatically generated, do not edit. -; Edit file manifest/main.ml instead. - -(executable - (name main) - (libraries - tezos-base - tezos-dal-015-PtLimaPt - tezos-protocol-015-PtLimaPt - tezos-base-test-helpers - tezos-015-PtLimaPt-test-helpers - alcotest-lwt) - (flags - (:standard) - -open Tezos_base.TzPervasives - -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals - -open Tezos_dal_015_PtLimaPt - -open Tezos_protocol_015_PtLimaPt - -open Tezos_base_test_helpers - -open Tezos_015_PtLimaPt_test_helpers)) - -(rule - (alias runtest) - (package tezos-dal-015-PtLimaPt) - (action (run %{dep:./main.exe}))) diff --git a/src/proto_015_PtLimaPt/lib_dal/test/main.ml b/src/proto_015_PtLimaPt/lib_dal/test/main.ml deleted file mode 100644 index 16eba46a8df5ae43a0b31caa8e323790ec505494..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_dal/test/main.ml +++ /dev/null @@ -1,55 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 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. *) -(* *) -(*****************************************************************************) - -module Unit_test : sig - (** - * Example: [spec "Slot_framing_protocol.ml" Test_dal_slot_frame_encoding.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 > unit" - [ - Unit_test.spec - "Slot_framing_protocol.ml" - Test_dal_slot_frame_encoding.tests; - ] - |> Lwt_main.run diff --git a/src/proto_015_PtLimaPt/lib_dal/test/test_dal_slot_frame_encoding.ml b/src/proto_015_PtLimaPt/lib_dal/test/test_dal_slot_frame_encoding.ml deleted file mode 100644 index 53da8377f099f5c1b200086a6aabe25f9bea2e9e..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_dal/test/test_dal_slot_frame_encoding.ml +++ /dev/null @@ -1,413 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 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: Dal_node Slot_frame_encoding - Invocation: dune exec src/proto_alpha/lib_dal/test/main.exe \ - -- test "^\[Unit\] Slot_framing_protocol.ml$" - Subject: Tests for the SCORU storage module -*) - -(* FIXME/DAL: https://gitlab.com/tezos/tezos/-/issues/3421 - Property based tests to check basic invariants of slot-frame encoding V0. *) - -open Protocol -open Alpha_context -module Rollup_messages_map = Dal_slot_frame_encoding.Rollups_map -module V0 = Dal_slot_frame_encoding.V0 - -(* FIXME/DAL: https://gitlab.com/tezos/tezos/-/issues/3339 - Fetch this value from protocol default constants *) -let max_size = 1_048_576 - -let assert_fails_with ~loc k expected_err = - let open Lwt_result_syntax in - let*! res = k in - Assert.error ~loc res (( = ) expected_err) - -module Compare_list_string = Compare.List (String) -module Compare_list_list_string = Compare.List (Compare_list_string) -module Compare_list_rollup = Compare.List (Sc_rollup.Address) - -let assert_equal_bytes ~loc msg = - Assert.equal ~loc Bytes.equal msg String.pp_bytes_hex - -let assert_equal_list_string ~loc msg = - Assert.equal - ~loc - Compare_list_string.equal - msg - (Format.pp_print_list Format.pp_print_string) - -let assert_equal_list_list_string ~loc msg = - Assert.equal - ~loc - Compare_list_list_string.equal - msg - (Format.pp_print_list (Format.pp_print_list Format.pp_print_string)) - -let assert_equal_list_rollups ~loc msg = - Assert.equal - ~loc - Compare_list_rollup.equal - msg - (Format.pp_print_list Sc_rollup.Address.pp) - -let sc_rollup_1 = - Sc_rollup.Address.of_b58check_exn "scr1HLXM32GacPNDrhHDLAssZG88eWqCUbyLF" - -let sc_rollup_2 = - Sc_rollup.Address.of_b58check_exn "scr1VAWKSdtzLy2LUarsowyAVwrmC1vmXduF3" - -let slot_frame_encoding_size_correct_single_v0 () = - let open Lwt_result_syntax in - let messages_rollup_1 = - ["hello"; "is"; "it"; "me"; "you"; "are"; "looking"; "for"] - in - (* One rollup with offset should take 24 bytes *) - let entry_size = V0.Internal.rollup_entry_size in - let* () = Assert.equal_int ~loc:__LOC__ entry_size 24 in - (* 1 byte for version *) - let expected_version_size = 1 in - (* 20 bytes for one rollup address + 4 bytes of offset + 4 bytes for frame length = 28 bytes *) - let computed_rollups_frame_size = V0.Internal.rollups_frame_size 1 in - let expected_rollups_frame_size = 28 in - let* () = - Assert.equal_int - ~loc:__LOC__ - computed_rollups_frame_size - expected_rollups_frame_size - in - (*27 bytes total messages + - 4 * 8 = 32 bytes message length prefixes + - 4 bytes list length prefix + - 63 bytes for messages frame *) - let computed_messages_frame_size = - V0.Internal.messages_frame_size messages_rollup_1 - in - let expected_messages_frame_size = 63 in - let* () = - Assert.equal_int - ~loc:__LOC__ - computed_messages_frame_size - expected_messages_frame_size - in - (* 4 bytes of list length prefix + - 63 bytes of messages_frame_size = 67 bytes for all messages frames *) - let computed_all_messages_frames_size = - V0.Internal.all_messages_frames_size [messages_rollup_1] - in - let expected_all_messages_frames_size = 4 + expected_messages_frame_size in - let* () = - Assert.equal_int - ~loc:__LOC__ - computed_all_messages_frames_size - expected_all_messages_frames_size - in - let expected_size = - expected_version_size + expected_rollups_frame_size - + expected_all_messages_frames_size - in - let map = - Rollup_messages_map.empty - |> Rollup_messages_map.add sc_rollup_1 messages_rollup_1 - in - let computed_size = V0.expected_slot_size map in - Assert.equal_int ~loc:__LOC__ expected_size computed_size - -let slot_frame_encoding_size_correct_multiple_v0 () = - let open Lwt_result_syntax in - let messages_rollup_1 = ["Summer"; "loving"; "had"; "me"; "a"; "blast"] in - let messages_rollup_2 = ["Summer"; "loving"; "happened"; "so"; "fast"] in - (* 1 byte for version *) - let expected_version_size = 1 in - (* 24 * 2 = 48 bytes for two rollup entries + - 4 bytes for frame length prefix = 52 bytes - *) - let computed_rollups_frame_size = V0.Internal.rollups_frame_size 2 in - let expected_rollups_frame_size = 52 in - let* () = - Assert.equal_int - ~loc:__LOC__ - computed_rollups_frame_size - expected_rollups_frame_size - in - (* Frame 1: - 6 + 6 + 3 + 2 + 1 + 5 = 23 bytes for messages + - 4 * 6 = 24 bytes for message length prefix for 6 messages - + 4 bytes for message frame prefix = - 51 bytes for the messages frame for rollup1. - Frame 2: - 6 + 6 + 8 + 2 + 4 = 26 bytes for messages + - 4 * 5 = 20 bytes for message length prefix for 6 messages - + 4 bytes for message frame prefix = - 50 bytes for the messages frame for rollup2. - Messages frame length: - 51 bytes for rollup1 messages frame + - 50 bytes for rollup2 messages frame + - 4 bytes prefix length for all messages frames = - 105 bytes - *) - let computed_all_messages_frames_size = - V0.Internal.all_messages_frames_size [messages_rollup_1; messages_rollup_2] - in - let expected_all_messages_frames_size = 105 in - let* () = - Assert.equal_int - ~loc:__LOC__ - computed_all_messages_frames_size - expected_all_messages_frames_size - in - let expected_size = - expected_version_size + expected_rollups_frame_size - + expected_all_messages_frames_size - in - let map = - Rollup_messages_map.empty - |> Rollup_messages_map.add sc_rollup_1 messages_rollup_1 - |> Rollup_messages_map.add sc_rollup_2 messages_rollup_2 - in - let computed_size = V0.expected_slot_size map in - Assert.equal_int ~loc:__LOC__ expected_size computed_size - -let slot_frame_encoding_decoding_correct_single_v0 () = - let open Lwt_result_syntax in - let messages_rollup_1 = - ["hello"; "is"; "it"; "me"; "you"; "are"; "looking"; "for"] - in - let messages_map = - Rollup_messages_map.empty - |> Rollup_messages_map.add sc_rollup_1 messages_rollup_1 - in - let* serialized = V0.serialize ~max_size messages_map in - let* () = - Assert.equal_int - ~loc:__LOC__ - (String.length serialized) - (V0.expected_slot_size messages_map) - in - let* deserialized = V0.deserialize ~max_size serialized in - let rollups_with_messages = Rollup_messages_map.bindings deserialized in - let* () = - assert_equal_list_rollups - ~loc:__LOC__ - "Deserialized rollups are different from originals" - [sc_rollup_1] - (List.map fst rollups_with_messages) - in - assert_equal_list_list_string - ~loc:__LOC__ - "Messages frames are different from originals" - [messages_rollup_1] - (List.map snd rollups_with_messages) - -let slot_frame_encoding_decoding_correct_multiple_v0 () = - let open Lwt_result_syntax in - let messages_rollup_1 = ["Summer"; "loving"; "had"; "me"; "a"; "blast"] in - let messages_rollup_2 = ["Summer"; "loving"; "happened"; "so"; "fast"] in - let messages_map = - Rollup_messages_map.empty - |> Rollup_messages_map.add sc_rollup_1 messages_rollup_1 - |> Rollup_messages_map.add sc_rollup_2 messages_rollup_2 - in - let* serialized = V0.serialize ~max_size messages_map in - let* () = - Assert.equal_int - ~loc:__LOC__ - (String.length serialized) - (V0.expected_slot_size messages_map) - in - let* deserialized = V0.deserialize ~max_size serialized in - let rollups_with_messages = Rollup_messages_map.bindings deserialized in - let* () = - assert_equal_list_rollups - ~loc:__LOC__ - "Deserialized rollups are different from originals" - [sc_rollup_1; sc_rollup_2] - (List.map fst rollups_with_messages) - in - assert_equal_list_list_string - ~loc:__LOC__ - "Messages frames are different from originals" - [messages_rollup_1; messages_rollup_2] - (List.map snd rollups_with_messages) - -let slot_frame_encoding_fails_if_too_big () = - let messages_rollup_1 = ["Summer"; "loving"; "had"; "me"; "a"; "blast"] in - let messages_rollup_2 = ["Summer"; "loving"; "happened"; "so"; "fast"] in - let messages_map = - Rollup_messages_map.empty - |> Rollup_messages_map.add sc_rollup_1 messages_rollup_1 - |> Rollup_messages_map.add sc_rollup_2 messages_rollup_2 - in - let actual_size = V0.expected_slot_size messages_map in - let max_size = actual_size - 1 in - assert_fails_with - ~loc:__LOC__ - (V0.serialize ~max_size messages_map) - (Dal_slot_frame_encoding.Slot_size_is_too_big {actual_size; max_size}) - -let slot_frame_decoding_fails_if_too_big () = - let open Lwt_result_syntax in - let messages_rollup_1 = ["Summer"; "loving"; "had"; "me"; "a"; "blast"] in - let messages_rollup_2 = ["Summer"; "loving"; "happened"; "so"; "fast"] in - let messages_map = - Rollup_messages_map.empty - |> Rollup_messages_map.add sc_rollup_1 messages_rollup_1 - |> Rollup_messages_map.add sc_rollup_2 messages_rollup_2 - in - let actual_size = V0.expected_slot_size messages_map in - let* serialized = V0.serialize ~max_size:actual_size messages_map in - let max_size = actual_size - 1 in - assert_fails_with - ~loc:__LOC__ - (V0.deserialize ~max_size serialized) - (Dal_slot_frame_encoding.Slot_size_is_too_big {actual_size; max_size}) - -let slot_frame_decoding_fails_if_wrong_version () = - let open Lwt_result_syntax in - let messages_rollup_1 = ["Summer"; "loving"; "had"; "me"; "a"; "blast"] in - let messages_rollup_2 = ["Summer"; "loving"; "happened"; "so"; "fast"] in - let messages_map = - Rollup_messages_map.empty - |> Rollup_messages_map.add sc_rollup_1 messages_rollup_1 - |> Rollup_messages_map.add sc_rollup_2 messages_rollup_2 - in - let* serialized = - Dal_slot_frame_encoding.V0.serialize ~max_size messages_map - in - let serialized_wrong_version = - "\001" ^ String.sub serialized 1 (String.length serialized - 1) - in - assert_fails_with - ~loc:__LOC__ - (V0.deserialize ~max_size serialized_wrong_version) - (Dal_slot_frame_encoding.Wrong_slot_frame_version - {expected = 0; provided = 1}) - -let slot_frame_encoding_correct_offsets () = - let open Lwt_result_syntax in - let messages_rollup_1 = ["hello"; "world"] in - let messages_rollup_2 = ["CAFEBABE"; "CAFEDEAD"] in - let messages_map = - Rollup_messages_map.empty - |> Rollup_messages_map.add sc_rollup_1 messages_rollup_1 - |> Rollup_messages_map.add sc_rollup_2 messages_rollup_2 - in - let* serialized = V0.serialize ~max_size messages_map in - (* the value of the offset that denotes where the messages frame for - sc_rollup_1 starts can be found at offset 25 until 29 (excluded): - 1 byte for version + - 4 bytes for rollups frame prefix + - 20 bytes for rollup address = 25. - *) - let first_offset = - String.sub serialized 25 4 |> Data_encoding.(Binary.of_string_exn int32) - in - (* the value of the offset should be 57l: - 1 byte for version number + 4 bytes for rollups frame prefix + - 2 * 24 bytes for rollups frame + - 4 bytes for messages frames prefix = 57. *) - let* () = Assert.equal_int32 ~loc:__LOC__ first_offset 57l in - (* The length of the first messages frame should be 22 bytes: - 4 bytes for the messages frame prefix + - 4 + 5 bytes for the encoding of the message "hello" + - 4 + 5 bytes for the encoding of the message "world" = 22. - *) - let first_messages_frame = - Data_encoding.(Binary.of_string_exn @@ list string) - @@ String.sub serialized 57 22 - in - let* () = - assert_equal_list_string - ~loc:__LOC__ - "Messages frame for sc_rollup_1 is not as expected" - first_messages_frame - ["hello"; "world"] - in - (* The value of the offset that denotes where the messages frame for - sc_rollup_2 STARTS can be found at bytes 49 until 53 (excluded): - 29 offset where the entry for sc_rollup_2 starts + - 20 bytes for the encoding of sc_rollup_2 = 49. - *) - let second_offset = - String.sub serialized 49 4 |> Data_encoding.(Binary.of_string_exn int32) - in - (* the value of the second offset should be 79 - 57 offset where the messages frame for sc_rollup_1 starts + - 22 bytes length of the first messages frame = 79 - *) - let* () = Assert.equal_int32 ~loc:__LOC__ second_offset 79l in - (* The length of the first messages frame should be 28: - 4 bytes for the messages frame prefix + - 4 + 8 bytes for the encoding of the message "CAFEBABE" + - 4 + 8 bytes for the encoding of the message "CAFEDEAD" = 28 - *) - let second_messages_frame = - Data_encoding.(Binary.of_string_exn @@ list string) - @@ String.sub serialized 79 28 - in - assert_equal_list_string - ~loc:__LOC__ - "Messages frame for sc_rollup_1 is not as expected" - second_messages_frame - ["CAFEBABE"; "CAFEDEAD"] - -let tests = - [ - Tztest.tztest - "Encoded slot has expected size (V0, 1 rollup)" - `Quick - slot_frame_encoding_size_correct_single_v0; - Tztest.tztest - "Encoded slot has expected size (V0, 2 rollups)" - `Quick - slot_frame_encoding_size_correct_multiple_v0; - Tztest.tztest - "Encoded slot can be decoded (V0, 1 rollup)" - `Quick - slot_frame_encoding_decoding_correct_single_v0; - Tztest.tztest - "Encoded slot can be decoded (V0, 2 rollups)" - `Quick - slot_frame_encoding_decoding_correct_multiple_v0; - Tztest.tztest - "Encoding of a slot over maximum size fails (V0)" - `Quick - slot_frame_encoding_fails_if_too_big; - Tztest.tztest - "Offsets of messages frames are correct (V0)" - `Quick - slot_frame_encoding_correct_offsets; - Tztest.tztest - "Slot decoding fails when slot size is too big (V0)" - `Quick - slot_frame_decoding_fails_if_too_big; - Tztest.tztest - "Slot decoding fails when first byte has wrong version (V0)" - `Quick - slot_frame_decoding_fails_if_wrong_version; - ] diff --git a/src/proto_015_PtLimaPt/lib_layer2_utils/dune b/src/proto_015_PtLimaPt/lib_layer2_utils/dune deleted file mode 100644 index 9da14e2f050c1d141dbc385f6bec40a5f208ce7a..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_layer2_utils/dune +++ /dev/null @@ -1,21 +0,0 @@ -; This file was automatically generated, do not edit. -; Edit file manifest/main.ml instead. - -(library - (name tezos_layer2_utils_015_PtLimaPt) - (public_name tezos-layer2-utils-015-PtLimaPt) - (instrumentation (backend bisect_ppx)) - (libraries - tezos-base - tezos-protocol-015-PtLimaPt - tezos-client-015-PtLimaPt - tezos-rpc) - (inline_tests (flags -verbose) (modes native)) - (preprocess (pps ppx_expect)) - (library_flags (:standard -linkall)) - (flags - (:standard) - -open Tezos_base.TzPervasives - -open Tezos_protocol_015_PtLimaPt - -open Tezos_client_015_PtLimaPt - -open Tezos_rpc)) diff --git a/src/proto_015_PtLimaPt/lib_layer2_utils/layer1_services.ml b/src/proto_015_PtLimaPt/lib_layer2_utils/layer1_services.ml deleted file mode 100644 index 22773e17db82ac5acb19a5b6545bcce5d4534c08..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_layer2_utils/layer1_services.ml +++ /dev/null @@ -1,129 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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.Alpha_block_services - -type 'accu successful_operation_processor = { - apply : - 'kind. - 'accu -> - source:public_key_hash -> - 'kind manager_operation -> - 'kind Apply_results.successful_manager_operation_result -> - 'accu; - apply_internal : - 'kind. - 'accu -> - source:public_key_hash -> - 'kind Apply_internal_results.internal_operation -> - 'kind Apply_internal_results.successful_internal_operation_result -> - 'accu; -} - -type 'accu operation_processor = { - apply : - 'kind. - 'accu -> - source:public_key_hash -> - 'kind manager_operation -> - 'kind Apply_results.manager_operation_result -> - 'accu; - apply_internal : - 'kind. - 'accu -> - source:public_key_hash -> - 'kind Apply_internal_results.internal_operation -> - 'kind Apply_internal_results.internal_operation_result -> - 'accu; -} - -let process_manager_operations operations accu f = - let rec on_operation_and_result : - type kind. _ -> kind Apply_results.contents_and_result_list -> _ = - fun accu -> function - | Single_and_result - ( Manager_operation {operation; source; _}, - Manager_operation_result - {operation_result; internal_operation_results; _} ) -> - let accu = f.apply accu ~source operation operation_result in - on_internal_operations accu source internal_operation_results - | Single_and_result (_, _) -> accu - | Cons_and_result - ( Manager_operation {operation; source; _}, - Manager_operation_result - {operation_result; internal_operation_results; _}, - rest ) -> - let accu = f.apply accu ~source operation operation_result in - let accu = - on_internal_operations accu source internal_operation_results - in - on_operation_and_result accu rest - and on_internal_operations accu source internal_operation_results = - let open Apply_internal_results in - List.fold_left - (fun accu (Internal_operation_result (operation, result)) -> - f.apply_internal accu ~source operation result) - accu - internal_operation_results - in - let process_contents accu - ({protocol_data = Operation_data {contents; _}; receipt; _} : operation) = - match receipt with - | Empty | Too_large | Receipt No_operation_metadata -> - (* This should case should not happen between [operations] is supposed - to be retrieved with `force_metadata:true` and assuming that the - tezos node is running in archive mode. *) - assert false - | Receipt (Operation_metadata {contents = results; _}) -> ( - match Apply_results.kind_equal_list contents results with - | Some Eq -> - on_operation_and_result accu - @@ Apply_results.pack_contents_list contents results - | None -> - (* Should not happen *) - assert false) - in - let process_operations = List.fold_left process_contents in - List.fold_left process_operations operations accu - -let process_applied_manager_operations operations accu - (f : _ successful_operation_processor) = - let apply (type kind) accu ~source (operation : kind manager_operation) - (result : kind Apply_results.manager_operation_result) = - match result with - | Applied result -> f.apply accu ~source operation result - | _ -> accu - in - let apply_internal (type kind) accu ~source - (operation : kind Apply_internal_results.internal_operation) - (result : kind Apply_internal_results.internal_operation_result) = - match result with - | Applied result -> f.apply_internal accu ~source operation result - | _ -> accu - in - process_manager_operations operations accu {apply; apply_internal} diff --git a/src/proto_015_PtLimaPt/lib_layer2_utils/layer1_services.mli b/src/proto_015_PtLimaPt/lib_layer2_utils/layer1_services.mli deleted file mode 100644 index bbcf372491af5e1f66c5f9e0e951ef2dbb69575a..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_layer2_utils/layer1_services.mli +++ /dev/null @@ -1,74 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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.Alpha_block_services - -type 'accu successful_operation_processor = { - apply : - 'kind. - 'accu -> - source:public_key_hash -> - 'kind manager_operation -> - 'kind Apply_results.successful_manager_operation_result -> - 'accu; - apply_internal : - 'kind. - 'accu -> - source:public_key_hash -> - 'kind Apply_internal_results.internal_operation -> - 'kind Apply_internal_results.successful_internal_operation_result -> - 'accu; -} - -type 'accu operation_processor = { - apply : - 'kind. - 'accu -> - source:public_key_hash -> - 'kind manager_operation -> - 'kind Apply_results.manager_operation_result -> - 'accu; - apply_internal : - 'kind. - 'accu -> - source:public_key_hash -> - 'kind Apply_internal_results.internal_operation -> - 'kind Apply_internal_results.internal_operation_result -> - 'accu; -} - -(** [process_manager_operations accu operations operator] folds over the list of - manager operations in [operations] applying [operator] to transform [accu] - along the way. *) -val process_manager_operations : - 'a -> operation list list -> 'a operation_processor -> 'a - -(** [process_applied_manager_operations accu operations operator] folds over the - list of applied manager operations in [operations] applying [operator] to - transform [accu] along the way. *) -val process_applied_manager_operations : - 'a -> operation list list -> 'a successful_operation_processor -> 'a diff --git a/src/proto_015_PtLimaPt/lib_protocol/test/pbt/dune b/src/proto_015_PtLimaPt/lib_protocol/test/pbt/dune index e565d92b4cdb88753b076909f814e5fc38d961be..68e9a95af65cb9b7f16b6b6aa42bcd7794ec9593 100644 --- a/src/proto_015_PtLimaPt/lib_protocol/test/pbt/dune +++ b/src/proto_015_PtLimaPt/lib_protocol/test/pbt/dune @@ -14,7 +14,6 @@ test_bitset test_sc_rollup_tick_repr test_sc_rollup_encoding - test_refutation_game test_carbonated_map test_zk_rollup_encoding) (libraries @@ -29,8 +28,7 @@ qcheck-alcotest tezos-benchmark tezos-benchmark-015-PtLimaPt - tezos-benchmark-type-inference-015-PtLimaPt - tezos-sc-rollup-015-PtLimaPt) + tezos-benchmark-type-inference-015-PtLimaPt) (flags (:standard) -open Tezos_base.TzPervasives @@ -39,8 +37,7 @@ -open Tezos_protocol_015_PtLimaPt -open Tezos_015_PtLimaPt_test_helpers -open Tezos_benchmark_015_PtLimaPt - -open Tezos_benchmark_type_inference_015_PtLimaPt - -open Tezos_sc_rollup_015_PtLimaPt)) + -open Tezos_benchmark_type_inference_015_PtLimaPt)) (rule (alias runtest) @@ -97,11 +94,6 @@ (package tezos-protocol-015-PtLimaPt-tests) (action (run %{dep:./test_sc_rollup_encoding.exe}))) -(rule - (alias runtest) - (package tezos-protocol-015-PtLimaPt-tests) - (action (run %{dep:./test_refutation_game.exe}))) - (rule (alias runtest) (package tezos-protocol-015-PtLimaPt-tests) @@ -134,8 +126,6 @@ (rule (alias runtest2) (action (run %{exe:test_sc_rollup_encoding.exe}))) -(rule (alias runtest3) (action (run %{exe:test_refutation_game.exe}))) - (rule (alias runtest3) (action (run %{exe:test_carbonated_map.exe}))) (rule (alias runtest3) (action (run %{exe:test_zk_rollup_encoding.exe}))) diff --git a/src/proto_015_PtLimaPt/lib_protocol/test/pbt/test_refutation_game.ml b/src/proto_015_PtLimaPt/lib_protocol/test/pbt/test_refutation_game.ml deleted file mode 100644 index f888a3046750c4055486f4b1ce2610696f52d907..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_protocol/test/pbt/test_refutation_game.ml +++ /dev/null @@ -1,1677 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* Copyright (c) 2022 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: PBT for the SCORU refutation game - Invocation: dune exec \ - src/proto_alpha/lib_protocol/test/pbt/test_refutation_game.exe - Subject: SCORU refutation game -*) -open Protocol - -open Alpha_context -open Sc_rollup -open Lib_test.Qcheck2_helpers - -(** {2 Utils} *) - -let qcheck_make_lwt = qcheck_make_lwt ~extract:Lwt_main.run - -let qcheck_make_lwt_res ?print ?count ~name ~gen f = - qcheck_make_result - ~pp_error:Error_monad.pp_print_trace - ?print - ?count - ~name - ~gen - (fun a -> Lwt_main.run (f a)) - -(** Lift a computation using environment errors to use shell errors. *) -let lift k = Lwt.map Environment.wrap_tzresult k - -let tick_to_int_exn ?(__LOC__ = __LOC__) t = - WithExceptions.Option.get ~loc:__LOC__ (Tick.to_int t) - -let tick_of_int_exn ?(__LOC__ = __LOC__) n = - WithExceptions.Option.get ~loc:__LOC__ (Tick.of_int n) - -let number_of_ticks_of_int64_exn ?(__LOC__ = __LOC__) n = - WithExceptions.Option.get ~loc:__LOC__ (Number_of_ticks.of_value n) - -let make_external_inbox_message str = - WithExceptions.Result.get_ok - ~loc:__LOC__ - Inbox_message.(External str |> serialize) - -let game_status_of_refute_op_result = function - | [ - Apply_results.Operation_metadata - { - contents = - Single_result - (Manager_operation_result - { - operation_result = - Applied (Sc_rollup_refute_result {game_status; _}); - _; - }); - }; - ] -> - game_status - | _ -> assert false - -let list_assoc (key : Tick.t) list = List.assoc ~equal:( = ) key list - -let print_dissection_chunk = Format.asprintf "%a" Game.pp_dissection_chunk - -let print_dissection = Format.asprintf "%a" Game.pp_dissection - -let print_our_states _ = "" - -let expect_invalid_move expected = function - | Error (Game.Invalid_move reason) -> - if reason = expected then true - else - let pp = Game.pp_invalid_move in - QCheck2.Test.fail_reportf - "@[Expected reason: %a@;Actual reason: %a@]" - pp - expected - pp - reason - | _ -> false - -let initial_of_dissection dissection = - List.hd dissection |> WithExceptions.Option.get ~loc:__LOC__ - -(** Modify the last section of a dissection. *) -let rec modify_stop f dissection = - match dissection with - | [] -> assert false - | [chunk] -> [f chunk] - | x :: xs -> - let xs = modify_stop f xs in - x :: xs - -(** Modify the first section of a dissection. *) -let modify_start f dissection = - match dissection with - | chunk :: xs -> f chunk :: xs - | [] -> (* The dissection can not be empty. *) assert false - -(** Checks that the [dissection] is valid regarding the function - {!Sc_rollup_game_repr.check_dissection}. *) -let valid_dissection ~default_number_of_sections ~start_chunk ~stop_chunk - dissection = - let open Lwt_syntax in - let* res = - Game.Internal_for_tests.check_dissection - ~default_number_of_sections - ~start_chunk - ~stop_chunk - dissection - in - return (Result.is_ok res) - -(** [disputed_sections ~our_states dissection] returns the list of sections - in the [dissection] on which the player dissecting disagree with. - It uses [our_states], an assoc list between tick and state hashes to - compare opponent's claims against our point of view. *) -let disputed_sections ~our_states dissection = - let open Game in - let agree_on_state tick their_state = - let our_state = list_assoc tick our_states in - Option.equal State_hash.equal our_state their_state - in - let rec traverse acc = function - | ({state_hash = their_start_state; tick = start_tick} as a) - :: ({state_hash = their_stop_state; tick = stop_tick} as b) - :: dissection -> - let rst = b :: dissection in - if agree_on_state start_tick their_start_state then - (* It's a disputed section if we agree on the start state but disagree - on the stop. *) - if agree_on_state stop_tick their_stop_state then traverse acc rst - else - let disputed_section = (a, b) in - traverse (disputed_section :: acc) rst - else traverse acc rst - | _ -> acc - in - traverse [] dissection - -let pick_disputed_sections disputed_sections = - QCheck2.Gen.oneofl disputed_sections - -let single_tick_disputed_sections disputed_sections = - List.filter_map - (fun disputed_section -> - let Game.({tick = a_tick; _}, {tick = b_tick; _}) = disputed_section in - let distance = Tick.distance a_tick b_tick in - if Z.Compare.(distance = Z.one) then Some disputed_section else None) - disputed_sections - -let final_dissection ~our_states dissection = - let disputed_sections = disputed_sections ~our_states dissection in - let single_tick_disputed_sections = - single_tick_disputed_sections disputed_sections - in - Compare.List_length_with.(single_tick_disputed_sections > 0) - -(** Build a non-random dissection from [start_chunk] to [stop_chunk] using - [our_states] as the state hashes for each tick. *) -let build_dissection ~number_of_sections ~start_chunk ~stop_chunk ~our_states = - let open Lwt_result_syntax in - let state_hash_from_tick tick = return @@ list_assoc tick our_states in - let our_stop_chunk = - Game.{stop_chunk with state_hash = list_assoc stop_chunk.tick our_states} - in - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3491 - - This dissection's building does not check the number of sections. Checks should - be added to verify that we don't generate invalid dissection and test the - incorrect cases. *) - Lwt_main.run - @@ let*! r = - Game_helpers.new_dissection - ~start_chunk - ~our_stop_chunk - ~default_number_of_sections:number_of_sections - ~state_hash_from_tick - in - Lwt.return @@ WithExceptions.Result.get_ok ~loc:__LOC__ r - -let originate_rollup originator messager ~first_inputs block = - let open Lwt_result_syntax in - let* origination_operation, sc_rollup = - Op.sc_rollup_origination - (B block) - originator - Kind.Example_arith - ~boot_sector:"" - ~parameters_ty:(Script.lazy_expr @@ Expr.from_string "unit") - in - let* add_message_operation = - Op.sc_rollup_add_messages (B block) messager sc_rollup first_inputs - in - let* block = - Block.bake ~operations:[origination_operation; add_message_operation] block - in - let+ genesis_info = Context.Sc_rollup.genesis_info (B block) sc_rollup in - (block, sc_rollup, genesis_info) - -(** [create_ctxt account1 account2] creates a context where - an arith rollup was originated, and both [account1] and [account2] owns - enough tez to stake on a commitment. *) -let create_ctxt ~first_inputs = - WithExceptions.Result.get_ok ~loc:__LOC__ - @@ Lwt_main.run - @@ - let open Lwt_result_syntax in - let* block, (account1, account2, account3) = - Context.init3 - ~sc_rollup_enable:true - ~consensus_threshold:0 - ~initial_balances:[100_000_000_000L; 100_000_000_000L; 100_000_000_000L] - () - in - let* block, sc_rollup, genesis_info = - originate_rollup account3 account1 ~first_inputs block - in - return (block, sc_rollup, genesis_info, (account1, account2, account3)) - -(** {2 Context free generators} *) - -(** Generate a {!State_hash.t}. - - We use a dirty hack {!QCheck2.Gen.make_primitive} to remove the - automatic shrinking. Shrinking on the states in a dissection can - be confusing, it can leads to a shrunk list with the same states in - each cell. -*) -let gen_random_hash = - let open QCheck2.Gen in - let gen = - let* x = bytes_fixed_gen 32 in - return @@ State_hash.of_bytes_exn x - in - (* This is not beautiful, but there is currently no other way to - remove the shrinker. *) - make_primitive - ~gen:(fun rand -> generate1 ~rand gen) - ~shrink:(fun _ -> Seq.empty) - -(** Generate the number of sections in the dissection. *) -let gen_num_sections = - let open Tezos_protocol_015_PtLimaPt_parameters.Default_parameters in - let testnet = constants_test.sc_rollup.number_of_sections_in_dissection in - let mainnet = constants_mainnet.sc_rollup.number_of_sections_in_dissection in - let sandbox = constants_sandbox.sc_rollup.number_of_sections_in_dissection in - QCheck2.Gen.( - frequency - [(5, pure mainnet); (4, pure testnet); (2, pure sandbox); (1, 4 -- 100)]) - -(** Generate a tick. *) -let gen_tick ?(lower_bound = 0) ?(upper_bound = 10_000) () = - let open QCheck2.Gen in - let+ tick = lower_bound -- upper_bound in - tick_of_int_exn ~__LOC__ tick - -(** [gen_arith_pvm_inputs ~gen_size] is a `correct list` generator. - It generates a list of strings that are either integers or `+` to be - consumed by the arithmetic PVM. - If a `+` is found then the previous two element of the stack are poped - then added and the result is pushed to the stack. In particular, - lists like `[1 +]` are incorrect. *) -let gen_arith_pvm_inputs ~gen_size = - let open QCheck2.Gen in - (* To preserve the correctness invariant, genlist is a recursive generator - that produce a pair `(stack_size, state_list)` where state_list is a - correct list of integers and `+` and consuming it will produce a `stack` - of length `stack_size`. - For example a result can be `(3, [1; 2; +; 3; +; 2; 2; +; 1;]). - Consuming the list will produce the stack`[6; 4; 1]` which has length 3. *) - let produce_inputs self fuel = - match fuel with - | 0 -> map (fun x -> (1, [string_of_int x])) small_nat - | n -> - (* The generator has two branches. - 1. with frequency 1 adds integers to state_list and increases the - corresponding stack_size. - 2. With frequency 2, at each step, it looks at the inductive result - [(self (n - 1)) = (stack_size, state_list)]. - - If the stack_size is smaller than 2 then it adds an integer to the - state_list and increases the stack_size. Otherwise, it adds a plus - to the state_list and decreases the stack_size. *) - frequency - [ - ( 2, - map2 - (fun x (stack_size, state_list) -> - if stack_size >= 2 then (stack_size - 1, "+" :: state_list) - else (stack_size + 1, string_of_int x :: state_list)) - small_nat - (self (n / 2)) ); - ( 1, - map2 - (fun x (i, y) -> (i + 1, string_of_int x :: y)) - small_nat - (self (n / 2)) ); - ] - in - let+ inputs = sized_size gen_size @@ fix produce_inputs in - snd inputs |> List.rev |> String.concat " " - -(** Generate a list of arith pvm inputs for a level *) -let gen_arith_pvm_inputs_for_level ?(level_min = 0) ?(level_max = 1_000) () = - let open QCheck2.Gen in - let* level = level_min -- level_max in - let* input = gen_arith_pvm_inputs ~gen_size:(pure 0) in - let* inputs = small_list (gen_arith_pvm_inputs ~gen_size:(pure 0)) in - return (level, input :: inputs) - -(** Generate a list of level and associated arith pvm inputs. *) -let gen_arith_pvm_inputs_for_levels ?(nonempty_inputs = false) ?level_min - ?level_max () = - let open QCheck2.Gen in - let rec aux () = - let* res = - let+ inputs_per_level = - small_list (gen_arith_pvm_inputs_for_level ?level_min ?level_max ()) - in - List.sort_uniq - (fun (l, _) (l', _) -> Compare.Int.compare l l') - inputs_per_level - in - if nonempty_inputs && Compare.List_length_with.(res = 0) then aux () - else return res - in - aux () - -(** Dissection helpers and tests *) -module Dissection = struct - (** Generate an initial *valid* dissection. The validity comes from a - mirrored implementation of {!Sc_rollup_game_repr.initial}. *) - let gen_initial_dissection ?ticks () = - let open QCheck2.Gen in - let* child_state = gen_random_hash and* parent_state = gen_random_hash in - let* ticks = - let+ ticks = - match ticks with - | None -> frequency [(1, pure 0); (9, 1 -- 1_000)] - | Some distance -> pure distance - in - Z.of_int ticks - in - let* initial_tick = gen_tick () in - if Z.Compare.(ticks = Z.zero) then - pure - [ - Game.{state_hash = Some child_state; tick = initial_tick}; - Game.{state_hash = None; tick = Tick.next initial_tick}; - ] - else - let tick = Tick.jump initial_tick ticks in - pure - [ - Game.{state_hash = Some parent_state; tick = initial_tick}; - Game.{state_hash = Some child_state; tick}; - Game.{state_hash = None; tick = Tick.next tick}; - ] - - (** Generate a *valid* dissection. - It returns the dissection alongside the dissected start_chunk and - stop_chunk, but also the number of sections used to generate the - dissection. *) - let gen_dissection ~number_of_sections ~our_states dissection = - let open QCheck2.Gen in - let disputed_sections = disputed_sections ~our_states dissection in - assert (Compare.List_length_with.(disputed_sections > 0)) ; - let+ start_chunk, stop_chunk = pick_disputed_sections disputed_sections in - let dissection = - build_dissection ~number_of_sections ~start_chunk ~stop_chunk ~our_states - in - (dissection, start_chunk, stop_chunk) - - let gen_initial_dissection_ticks = QCheck2.Gen.(0 -- 1_000) - - let gen_nonfinal_initial_dissection_ticks = QCheck2.Gen.(3 -- 1_000) - - (** Given an initial tick and state_hash: generates random state hashes for - every others [ticks]. - Having [our_states] provide the state hashes you believe to - be true. You can then generate a dissection from another one when - you disagree with some sections. *) - let gen_our_states start_chunk ticks = - let open QCheck2.Gen in - let Game.{tick = initial_tick; state_hash = initial_state_hash} = - start_chunk - in - let initial_state_hash = - WithExceptions.Option.get ~loc:__LOC__ initial_state_hash - in - let initial_tick_int = tick_to_int_exn initial_tick in - let rec aux acc i = - if i < 0 then return acc - else if i = 0 then return ((initial_tick, initial_state_hash) :: acc) - else - let* state_hash = gen_random_hash in - let tick = tick_of_int_exn (i + initial_tick_int) in - aux ((tick, state_hash) :: acc) (i - 1) - in - aux [] ticks - - (** {3 Dissection tests} *) - - let count = 300 - - (** Test the validity of dissection generated by {!gen_dissection} on - an initial dissection generated by {!gen_initial_dissection}. - It is a self test that'll help detect issues in subsequent tests; - in case the generator does not produce valid dissections. *) - let test_valid_gen_dissection = - let open QCheck2 in - let gen = - let open Gen in - let* number_of_sections = gen_num_sections in - let* ticks = gen_initial_dissection_ticks in - let* dissection = gen_initial_dissection ~ticks () in - let* our_states = - gen_our_states (initial_of_dissection dissection) (succ ticks) - in - if final_dissection ~our_states dissection then - (* The initial dissection could not be dissected. *) - return (dissection, None, number_of_sections, our_states) - else - let* new_dissection, start_hash, stop_hash = - gen_dissection ~number_of_sections ~our_states dissection - in - return - ( dissection, - Some (new_dissection, start_hash, stop_hash), - number_of_sections, - our_states ) - in - let print = - Print.( - quad - print_dissection - (option - (triple - print_dissection - print_dissection_chunk - print_dissection_chunk)) - int - print_our_states) - in - qcheck_make_lwt - ~count - ~name:"gen_dissection produces a valid dissection" - ~print - ~gen - (fun (dissection, new_dissection, default_number_of_sections, our_states) - -> - let open Lwt_syntax in - match new_dissection with - | None -> return (final_dissection ~our_states dissection) - | Some (new_dissection, start_chunk, stop_chunk) -> - valid_dissection - ~default_number_of_sections - ~start_chunk - ~stop_chunk - new_dissection) - - (** Truncate a [dissection] and expect the - {!Sc_rollup_game_repr.check_dissection} to fail with an invalid - number of sections, where [expected_number_of_sections] is expected. *) - let truncate_and_check_error dissection start_chunk stop_chunk - default_number_of_sections expected_number_of_sections = - let open Lwt_syntax in - let truncated_dissection = - match dissection with - | x :: _ :: z :: rst -> x :: z :: rst - | _ -> - (* If the dissection is valid, this case can not be reached. *) - assert false - in - let* res = - Game.Internal_for_tests.check_dissection - ~default_number_of_sections - ~start_chunk - ~stop_chunk - truncated_dissection - in - let expected_len = Z.of_int expected_number_of_sections in - let expected_reason = - Game.Dissection_number_of_sections_mismatch - {expected = expected_len; given = Z.pred expected_len} - in - return (expect_invalid_move expected_reason res) - - (** Test that if a dissection is smaller than the default number of - sections, the length is equal to (distance + 1) of the dissected - section. *) - let test_truncated_small_dissection = - let open QCheck2 in - qcheck_make_lwt - ~count - ~name: - "distance < nb_of_sections => (len dissection = succ (dist dissection))" - ~gen: - (let open Gen in - let* number_of_sections = gen_num_sections in - let* ticks = 3 -- (number_of_sections - 1) in - let* dissection = gen_initial_dissection ~ticks () in - let* our_states = - gen_our_states (initial_of_dissection dissection) (succ ticks) - in - let* new_dissection, start_hash, stop_hash = - gen_dissection ~number_of_sections ~our_states dissection - in - return (new_dissection, start_hash, stop_hash, number_of_sections, ticks)) - (fun ( dissection, - start_chunk, - stop_chunk, - default_number_of_sections, - distance ) -> - let expected_len = succ distance in - truncate_and_check_error - dissection - start_chunk - stop_chunk - default_number_of_sections - expected_len) - - (** Test that if the distance in the dissected section is larger than - the default number of sections, the dissection length is exactly the - default number of sections. *) - let test_truncated_large_dissection = - let open QCheck2 in - qcheck_make_lwt - ~count - ~name:"distance >= nb_of_sections => (len dissection = nb_of_sections" - ~gen: - (let open Gen in - let* number_of_sections = gen_num_sections in - let* ticks = number_of_sections -- 1_000 in - let* dissection = gen_initial_dissection ~ticks () in - let* our_states = - gen_our_states (initial_of_dissection dissection) (succ ticks) - in - let* new_dissection, start_chunk, stop_chunk = - gen_dissection ~number_of_sections ~our_states dissection - in - return (new_dissection, start_chunk, stop_chunk, number_of_sections)) - (fun (dissection, start_chunk, stop_chunk, default_number_of_sections) -> - truncate_and_check_error - dissection - start_chunk - stop_chunk - default_number_of_sections - default_number_of_sections) - - (** Test that we can not change the start chunk of a section when we produce - a dissection. *) - let test_immutable_start_chunk = - let open QCheck2 in - qcheck_make_lwt - ~count - ~name:"dissection.start_chunk can not change" - ~gen: - (let open Gen in - let* number_of_sections = gen_num_sections in - let* ticks = gen_nonfinal_initial_dissection_ticks in - let* dissection = gen_initial_dissection ~ticks () in - let* our_states = - gen_our_states (initial_of_dissection dissection) (succ ticks) - in - let* new_dissection, start_chunk, stop_chunk = - gen_dissection ~number_of_sections ~our_states dissection - in - let* new_state_hash = gen_random_hash in - return - ( new_dissection, - start_chunk, - stop_chunk, - number_of_sections, - new_state_hash )) - (fun ( dissection, - start_chunk, - stop_chunk, - default_number_of_sections, - new_state_hash ) -> - let open Lwt_syntax in - (* Check that we can not change the start hash. *) - let dissection_with_different_start = - modify_start - (fun chunk -> Game.{chunk with state_hash = Some new_state_hash}) - dissection - in - let* res = - Game.Internal_for_tests.check_dissection - ~default_number_of_sections - ~start_chunk - ~stop_chunk - dissection_with_different_start - in - let expected_reason = - Game.Dissection_start_hash_mismatch - {expected = start_chunk.state_hash; given = Some new_state_hash} - in - return (expect_invalid_move expected_reason res)) - - (** Test that we can not produce a dissection that agrees with the stop hash. - Otherwise, there would be nothing to dispute. *) - let test_stop_hash_must_change = - let open QCheck2 in - qcheck_make_lwt - ~count - ~name:"dissection.stop_chunk must change" - ~gen: - (let open Gen in - let* number_of_sections = gen_num_sections in - let* ticks = gen_nonfinal_initial_dissection_ticks in - let* dissection = gen_initial_dissection ~ticks () in - let* our_states = - gen_our_states (initial_of_dissection dissection) (succ ticks) - in - let* new_dissection, start_chunk, stop_chunk = - gen_dissection ~number_of_sections ~our_states dissection - in - return (new_dissection, start_chunk, stop_chunk, number_of_sections)) - (fun (dissection, start_chunk, stop_chunk, default_number_of_sections) -> - let open Lwt_syntax in - let check_failure_on_same_stop_hash stop_hash = - let invalid_dissection = - modify_stop - (fun chunk -> Game.{chunk with state_hash = stop_hash}) - dissection - in - let stop_chunk = Game.{stop_chunk with state_hash = stop_hash} in - let* res = - Game.Internal_for_tests.check_dissection - ~default_number_of_sections - ~start_chunk - ~stop_chunk - invalid_dissection - in - let expected_reason = - Game.Dissection_stop_hash_mismatch stop_hash - (* match stop_hash with - * | None -> "The stop hash should not be None." - * | Some stop -> - * Format.asprintf - * "The stop hash should not be equal to %a" - * State_hash.pp - * stop *) - in - return (expect_invalid_move expected_reason res) - in - let* b1 = check_failure_on_same_stop_hash None in - let* b2 = check_failure_on_same_stop_hash stop_chunk.state_hash in - return (b1 && b2)) - - (** Test that we can not produce a dissection modifying the starting - end last point of a section. *) - let test_immutable_start_and_stop_ticks = - let open QCheck2 in - qcheck_make_lwt - ~count - ~name: - "start_chunk.tick and stop_chunk.tick can not change in the dissection" - ~gen: - (let open Gen in - let* number_of_sections = gen_num_sections in - let* ticks = gen_nonfinal_initial_dissection_ticks in - let* dissection = gen_initial_dissection ~ticks () in - let* our_states = - gen_our_states (initial_of_dissection dissection) (succ ticks) - in - let* new_dissection, start_chunk, stop_chunk = - gen_dissection ~number_of_sections ~our_states dissection - in - return (new_dissection, start_chunk, stop_chunk, number_of_sections)) - (fun (dissection, start_chunk, stop_chunk, default_number_of_sections) -> - let open Lwt_syntax in - let expected_reason dissection = - match (List.hd dissection, List.last_opt dissection) with - | Some Game.{tick = a_tick; _}, Some {tick = b_tick; _} -> - Game.Dissection_edge_ticks_mismatch - { - dissection_start_tick = a_tick; - dissection_stop_tick = b_tick; - chunk_start_tick = start_chunk.tick; - chunk_stop_tick = stop_chunk.tick; - } - | _ -> assert false - in - let modify_tick modify_X dissection = - let invalid_dissection = - modify_X - (fun chunk -> Game.{chunk with tick = Tick.next chunk.tick}) - dissection - in - let* res = - Game.Internal_for_tests.check_dissection - ~default_number_of_sections - ~start_chunk - ~stop_chunk - invalid_dissection - in - let expected_reason = expected_reason invalid_dissection in - return (expect_invalid_move expected_reason res) - in - (* We modify the start tick and expect the failure. *) - let* b1 = modify_tick modify_start dissection in - (* We modify the stop tick and expect the failure. *) - let* b2 = modify_tick modify_stop dissection in - return (b1 && b2)) - - (** Test that a valid dissection must have a proper distribution of the - sections. That is, a section should not be geq than half of the - dissected section's distance. *) - let test_badly_distributed_dissection = - let open QCheck2 in - qcheck_make_lwt - ~count - ~name:"dissection must be well distributed" - ~gen: - (let open Gen in - (* The test is not general enough to support all kind of number of - sections. *) - let number_of_sections = - Tezos_protocol_015_PtLimaPt_parameters.Default_parameters - .constants_mainnet - .sc_rollup - .number_of_sections_in_dissection - in - let* picked_section = 0 -- (number_of_sections - 2) in - let* ticks = 100 -- 1_000 in - let* dissection = gen_initial_dissection ~ticks () in - let* our_states = - gen_our_states (initial_of_dissection dissection) (succ ticks) - in - let* new_dissection, start_chunk, stop_chunk = - gen_dissection ~number_of_sections ~our_states dissection - in - return - ( new_dissection, - start_chunk, - stop_chunk, - number_of_sections, - picked_section )) - (fun ( dissection, - start_chunk, - stop_chunk, - default_number_of_sections, - picked_section ) -> - let open Lwt_syntax in - (* We put a distance of [1] in every section. Then, we put the - distance's left in the [picked_section], it will create - an invalid section. *) - let distance = - Z.succ @@ Tick.distance start_chunk.tick stop_chunk.tick - in - let max_section_length = - Z.(succ @@ (distance - of_int default_number_of_sections)) - in - let section_length = Z.one in - - (* Replace the distance of the first [k] sections by [section_length]. - In practice, when [k = 0], we're at the last section of the - dissection. *) - let rec replace_distances tick k = function - | a :: b :: xs -> - let b, tick = - if k = 0 then - let tick = Tick.jump tick max_section_length in - (Game.{b with tick}, tick) - else - let tick = Tick.jump tick section_length in - (Game.{b with tick}, tick) - in - a :: replace_distances tick (k - 1) (b :: xs) - | xs -> xs - in - let invalid_dissection = - replace_distances start_chunk.tick picked_section dissection - in - let* res = - Game.Internal_for_tests.check_dissection - ~default_number_of_sections - ~start_chunk - ~stop_chunk - invalid_dissection - in - let expected_reason = Game.Dissection_invalid_distribution in - - return (expect_invalid_move expected_reason res)) - - let tests = - ( "Dissection", - qcheck_wrap - [ - test_valid_gen_dissection; - test_truncated_small_dissection; - test_truncated_large_dissection; - test_immutable_start_chunk; - test_stop_hash_must_change; - test_immutable_start_and_stop_ticks; - test_badly_distributed_dissection; - ] ) -end - -(** {2. ArithPVM utils} *) - -module ArithPVM = Sc_rollup_helpers.Arith_pvm - -module Tree_inbox = struct - open Inbox - module Store = Tezos_context_memory.Context - - module Tree = struct - include Store.Tree - - type tree = Store.tree - - type t = Store.t - - type key = string list - - type value = bytes - end - - type t = Store.t - - type tree = Tree.tree - - let commit_tree store key tree = - let open Lwt_syntax in - let* store = Store.add_tree store key tree in - let* _ = Store.commit ~time:Time.Protocol.epoch store in - return () - - let lookup_tree store hash = - let open Lwt_syntax in - let index = Store.index store in - let* _, tree = - Store.produce_tree_proof - index - (`Node (Hash.to_context_hash hash)) - (fun x -> Lwt.return (x, x)) - in - return (Some tree) - - type proof = Store.Proof.tree Store.Proof.t - - let verify_proof proof f = - Lwt.map Result.to_option (Store.verify_tree_proof proof f) - - let produce_proof store tree f = - let open Lwt_syntax in - let index = Store.index store in - let* proof = Store.produce_tree_proof index (`Node (Tree.hash tree)) f in - return (Some proof) - - let kinded_hash_to_inbox_hash = function - | `Value hash | `Node hash -> Hash.of_context_hash hash - - let proof_before proof = kinded_hash_to_inbox_hash proof.Store.Proof.before - - let proof_encoding = - Tezos_context_merkle_proof_encoding.Merkle_proof_encoding.V1.Tree32 - .tree_proof_encoding -end - -module Store_inbox = struct - include Inbox.Make_hashing_scheme (Tree_inbox) -end - -module Arith_test_pvm = struct - include ArithPVM - - let init_context () = Tezos_context_memory.make_empty_context () - - let initial_state ctxt = - let open Lwt_syntax in - let* state = initial_state ctxt in - let* state = install_boot_sector state "" in - return state - - let initial_hash = - let open Lwt_syntax in - let* state = initial_state (init_context ()) in - state_hash state - - let mk_input level message_counter msg = - let payload = make_external_inbox_message msg in - let level = Int32.of_int level in - Sc_rollup.Inbox_message - {payload; message_counter; inbox_level = Raw_level.of_int32_exn level} - - let consume_fuel = Option.map pred - - let continue_with_fuel ~our_states ~(tick : int) fuel state f = - let open Lwt_syntax in - match fuel with - | Some 0 -> return (state, fuel, tick, our_states) - | _ -> f tick our_states (consume_fuel fuel) state - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3498 - - the following is almost the same code as in the rollup node, expect that it - creates the association list (tick, state_hash). *) - let eval_until_input ~fuel ~our_states start_tick state = - let open Lwt_syntax in - let eval_tick _tick state = eval state in - let rec go ~our_states fuel (tick : int) state = - let* input_request = is_input_state state in - match fuel with - | Some 0 -> return (state, fuel, tick, our_states) - | None | Some _ -> ( - match input_request with - | No_input_required -> - let* state = eval_tick tick state in - let* state_hash = state_hash state in - let our_states = (tick, state_hash) :: our_states in - go ~our_states (consume_fuel fuel) (tick + 1) state - | _ -> return (state, fuel, tick, our_states)) - in - go ~our_states fuel start_tick state - - let feed_input ~fuel ~our_states ~tick state input = - let open Lwt_syntax in - let* state, fuel, tick, our_states = - eval_until_input ~fuel ~our_states tick state - in - continue_with_fuel ~our_states ~tick fuel state - @@ fun tick our_states fuel state -> - let* state = set_input input state in - let* state_hash = state_hash state in - let our_states = (tick, state_hash) :: our_states in - let tick = tick + 1 in - let* state, fuel, tick, our_states = - eval_until_input ~fuel ~our_states tick state - in - return (state, fuel, tick, our_states) - - let eval_inbox ?fuel ~level ~inputs ~tick state = - let open Lwt_result_syntax in - List.fold_left_i_es - (fun message_counter (state, fuel, tick, our_states) input -> - let input = mk_input level (Z.of_int message_counter) input in - let*! state, fuel, tick, our_states = - feed_input ~fuel ~our_states ~tick state input - in - return (state, fuel, tick, our_states)) - (state, fuel, tick, []) - inputs - - let eval_levels_and_inputs ?fuel ctxt levels_and_inputs = - let open Lwt_result_syntax in - let*! state = initial_state ctxt in - let*! state_hash = state_hash state in - let our_states = [(0, state_hash)] in - let*! state, fuel, tick, our_states = - eval_until_input ~fuel ~our_states 1 state - in - let* state, _fuel, tick, our_states = - List.fold_left_es - (fun (state, fuel, tick, our_states) (level, inputs) -> - let* state, fuel, tick, our_states' = - eval_inbox ?fuel ~level ~inputs ~tick state - in - return (state, fuel, tick, our_states @ our_states')) - (state, fuel, tick, our_states) - levels_and_inputs - in - let our_states = - List.sort (fun (x, _) (y, _) -> Compare.Int.compare x y) our_states - in - let our_states = - List.map - (fun (tick_int, state) -> (tick_of_int_exn tick_int, state)) - our_states - in - let tick = tick_of_int_exn tick in - return (state, tick, our_states) -end - -(** Construct the inbox for the protocol side. *) -let construct_inbox_proto block rollup levels_and_inputs contract = - let open Lwt_result_syntax in - List.fold_left_es - (fun block (level, payloads) -> - let*? current_level = Context.get_level (B block) in - let diff_with_level = - Raw_level.(diff (of_int32_exn (Int32.of_int level)) current_level) - |> Int32.to_int - in - let* block = Block.bake_n (diff_with_level - 1) block in - let* operation_add_message = - Op.sc_rollup_add_messages (B block) contract rollup payloads - in - Block.bake ~operation:operation_add_message block) - block - levels_and_inputs - -(** Kind of strategy a player can play - - The cheaters will have their own version of inputs. This way, they - can produce valid proofs regarding their inboxes, but discarded by - the protocol. -*) -type strategy = - | Random (** A random player will execute its own random vision of inputs. *) - | Perfect - (** A perfect player, never lies, always win. - GSW 73-9 2014-2015 mindset. *) - | Lazy (** A lazy player will not execute all messages. *) - | Eager (** A eager player will not cheat until a certain point. *) - | Keen (** A keen player will execute more messages. *) - -let pp_strategy fmt = function - | Random -> Format.pp_print_string fmt "Random" - | Perfect -> Format.pp_print_string fmt "Perfect" - | Lazy -> Format.pp_print_string fmt "Lazy" - | Eager -> Format.pp_print_string fmt "Eager" - | Keen -> Format.pp_print_string fmt "Keen" - -type player = { - pkh : Signature.Public_key_hash.t; - contract : Contract.t; - strategy : strategy; - game_player : Game.player; -} - -let pp_player ppf {pkh; contract = _; strategy; game_player} = - Format.fprintf - ppf - "pkh: %a@,strategy: %a@,game_player: %s" - Signature.Public_key_hash.pp_short - pkh - pp_strategy - strategy - (if Game.player_equal game_player Alice then "Alice" else "Bob") - -type player_client = { - player : player; - states : (Tick.t * State_hash.t) list; - final_tick : Tick.t; - inbox : - Store_inbox.inbox_context - * Store_inbox.tree option - * Inbox.History.t - * Inbox.t; - levels_and_inputs : (int * string list) list; -} - -let pp_levels_and_inputs ppf levels_and_inputs = - Format.( - (pp_print_list - (fun ppf (level, inputs) -> - fprintf - ppf - "level %d, inputs %a" - level - (pp_print_list pp_print_string) - inputs) - ppf) - levels_and_inputs) - -let pp_player_client ppf - {player; states; final_tick; inbox = _; levels_and_inputs} = - Format.fprintf - ppf - "@[player:@,\ - %a@]@,\ - @[states:@,\ - %a@]@,\ - final tick: %a@,\ - @[levels and inputs:@,\ - %a@]@," - pp_player - player - (Format.pp_print_list (fun ppf (tick, hash) -> - Format.fprintf - ppf - "tick %a, state hash %a" - Tick.pp - tick - State_hash.pp_short - hash)) - states - Tick.pp - final_tick - (* inbox *) - pp_levels_and_inputs - levels_and_inputs - -module Player_client = struct - (** Transform inputs to payloads. *) - let levels_and_payloads levels_and_inputs = - List.map - (fun (level, inputs) -> - (level, List.map make_external_inbox_message inputs)) - levels_and_inputs - - let empty_memory_ctxt id = - let open Lwt_syntax in - Lwt_main.run - @@ let+ index = Tezos_context_memory.Context.init id in - Tezos_context_memory.Context.empty index - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3529 - - Factor code for the unit test. - this and {!Store_inbox} is highly copy-pasted from - test/unit/test_sc_rollup_inbox. The main difference is: we use - [Alpha_context.Sc_rollup.Inbox] instead of [Sc_rollup_repr_inbox] in the - former. *) - let construct_inbox ctxt levels_and_payloads ~rollup ~origination_level = - let open Lwt_syntax in - let open Store_inbox in - let* inbox = empty ctxt rollup origination_level in - let history = Inbox.History.empty ~capacity:10000L in - let rec aux history inbox level_tree = function - | [] -> return (ctxt, level_tree, history, inbox) - | (level, payloads) :: rst -> - let level = Int32.of_int level |> Raw_level.of_int32_exn in - let () = assert (Raw_level.(origination_level <= level)) in - let* res = - lift @@ add_messages ctxt history inbox level payloads level_tree - in - let level_tree, history, inbox = - WithExceptions.Result.get_ok ~loc:__LOC__ res - in - aux history inbox (Some level_tree) rst - in - aux history inbox None levels_and_payloads - - (** Construct an inbox based on [levels_and_inputs] in the player context. *) - let construct_inbox ~origination_level ctxt rollup levels_and_inputs = - Lwt_main.run - @@ construct_inbox - ~origination_level - ctxt - ~rollup - (levels_and_payloads levels_and_inputs) - - (** Generate [our_states] for [levels_and_inputs] based on the strategy. - It needs [level_min] and [level_max] in case it will need to generate - new inputs. *) - let gen_our_states ctxt strategy ?level_min ?level_max levels_and_inputs = - let open QCheck2.Gen in - let eval_inputs levels_and_inputs = - Lwt_main.run - @@ - let open Lwt_result_syntax in - let*! r = Arith_test_pvm.eval_levels_and_inputs ctxt levels_and_inputs in - Lwt.return @@ WithExceptions.Result.get_ok ~loc:__LOC__ r - in - match strategy with - | Perfect -> - (* The perfect player does not lie, evaluates correctly the inputs. *) - let _state, tick, our_states = eval_inputs levels_and_inputs in - return (tick, our_states, levels_and_inputs) - | Random -> - (* Random player generates its own list of inputs. *) - let* new_levels_and_inputs = - gen_arith_pvm_inputs_for_levels ?level_min ?level_max () - in - let _state, tick, our_states = eval_inputs new_levels_and_inputs in - return (tick, our_states, new_levels_and_inputs) - | Lazy -> - (* Lazy player removes inputs from [levels_and_inputs]. *) - let n = List.length levels_and_inputs in - let* remove_k = 1 -- n in - let new_levels_and_inputs = - List.take_n (n - remove_k) levels_and_inputs - in - let _state, tick, our_states = eval_inputs new_levels_and_inputs in - return (tick, our_states, new_levels_and_inputs) - | Eager -> - (* Eager player executes correctly the inbox until a certain point. *) - let nb_of_input = - List.fold_left - (fun acc (_level, inputs) -> acc + List.length inputs) - 0 - levels_and_inputs - in - let* corrupt_at_k = 0 -- (nb_of_input - 1) in - let new_input = "42 7 +" in - (* Once an input is corrupted, everything after will be corrupted - as well. *) - let new_levels_and_inputs = - let idx = ref (-1) in - List.map - (fun (level, inputs) -> - ( level, - List.map - (fun input -> - incr idx ; - if !idx = corrupt_at_k then new_input else input) - inputs )) - levels_and_inputs - in - let _state, tick, our_states = eval_inputs new_levels_and_inputs in - return (tick, our_states, new_levels_and_inputs) - | Keen -> - (* Keen player will add more messages. *) - let* new_levels_and_inputs = - gen_arith_pvm_inputs_for_levels ?level_min ?level_max () - in - let new_levels_and_inputs = new_levels_and_inputs @ levels_and_inputs in - let new_levels_and_inputs = - List.sort_uniq - (fun (l, _) (l', _) -> Compare.Int.compare l l') - new_levels_and_inputs - in - let _state, tick, our_states = eval_inputs new_levels_and_inputs in - return (tick, our_states, new_levels_and_inputs) - - (** [gen ~rollup ~level_min ~level_max player levels_and_inputs] generates - a {!player_client} based on {!player.strategy}. *) - let gen ~rollup ~origination_level ~level_min ~level_max player - levels_and_inputs = - let open QCheck2.Gen in - let ctxt = empty_memory_ctxt "foo" in - let* tick, our_states, levels_and_inputs = - gen_our_states - ctxt - player.strategy - ~level_min - ~level_max - levels_and_inputs - in - let inbox = - construct_inbox ~origination_level ctxt rollup levels_and_inputs - in - return - {player; final_tick = tick; states = our_states; inbox; levels_and_inputs} -end - -(** [create_commitment ~predecessor ~inbox_level ~our_states] creates - a commitment using [our_states] as the vision of ticks. *) -let create_commitment ~predecessor ~inbox_level ~our_states = - let open Lwt_syntax in - let inbox_level = Int32.of_int inbox_level |> Raw_level.of_int32_exn in - let+ compressed_state = - match List.last_opt our_states with - | None -> - (* No tick evaluated. *) - Arith_test_pvm.initial_hash - | Some (_, state) -> return state - in - - let number_of_ticks = - match our_states with - | [] -> Number_of_ticks.zero - | _ -> - List.length our_states - 1 - |> Int64.of_int |> number_of_ticks_of_int64_exn - in - Commitment.{compressed_state; inbox_level; predecessor; number_of_ticks} - -(** [operation_publish_commitment block rollup lcc inbox_level p1_client] - creates a commitment and stake on it. *) -let operation_publish_commitment ctxt rollup predecessor inbox_level - player_client = - let open Lwt_result_syntax in - let*! commitment = - create_commitment ~predecessor ~inbox_level ~our_states:player_client.states - in - Op.sc_rollup_publish ctxt player_client.player.contract rollup commitment - -(** [build_proof ~player_client start_tick game] builds a valid proof - regarding the vision [player_client] has. The proof refutes the - [start_tick]. *) -let build_proof ~player_client start_tick (game : Game.t) = - let open Lwt_result_syntax in - let inbox_context, messages_tree, history, inbox = player_client.inbox in - let* history, history_proof = - Lwt.map Environment.wrap_tzresult - @@ Store_inbox.form_history_proof inbox_context history inbox messages_tree - in - (* We start a game on a commitment that starts at [Tick.initial], the fuel - is necessarily [start_tick]. *) - let fuel = tick_to_int_exn start_tick in - let*! r = - Arith_test_pvm.eval_levels_and_inputs - ~fuel - (Arith_test_pvm.init_context ()) - player_client.levels_and_inputs - in - let state, _, _ = WithExceptions.Result.get_ok ~loc:__LOC__ r in - let module P = struct - include Arith_test_pvm - - let context = inbox_context - - let state = state - - let reveal _ = assert false - - module Inbox_with_history = struct - include Store_inbox - - let history = history - - let inbox = history_proof - end - end in - let*! proof = Sc_rollup.Proof.produce (module P) game.level in - return (WithExceptions.Result.get_ok ~loc:__LOC__ proof) - -(** [next_move ~number_of_sections ~player_client game] produces - the next move in the refutation game. - - If there is a disputed section where the distance is one tick, it - produces a proof. Otherwise, provides another dissection. -*) -let next_move ~player_client (game : Game.t) = - let open Lwt_result_syntax in - match game.game_state with - | Dissecting {dissection; default_number_of_sections} -> ( - let disputed_sections = - disputed_sections ~our_states:player_client.states dissection - in - assert (Compare.List_length_with.(disputed_sections > 0)) ; - let single_tick_disputed_sections = - single_tick_disputed_sections disputed_sections - in - match single_tick_disputed_sections with - | (start_chunk, _stop_chunk) :: _ -> - let tick = start_chunk.tick in - let+ proof = build_proof ~player_client tick game in - Game.{choice = tick; step = Proof proof} - | [] -> - (* If we reach this case, there is necessarily a disputed section. *) - let start_chunk, stop_chunk = Stdlib.List.hd disputed_sections in - let dissection = - build_dissection - ~number_of_sections:default_number_of_sections - ~start_chunk - ~stop_chunk - ~our_states:player_client.states - in - return Game.{choice = start_chunk.tick; step = Dissection dissection}) - | Final_move {agreed_start_chunk; refuted_stop_chunk = _} -> - let tick = agreed_start_chunk.tick in - let+ proof = build_proof ~player_client tick game in - Game.{choice = tick; step = Proof proof} - -type game_result_for_tests = Defender_wins | Refuter_wins - -(** Play until there is an {!game_result_for_tests}. - - A game result can happen if: - - A valid refutation was provided to the protocol and it succeeded to - win the game. - - A player played an invalid refutation and was rejected by the - protocol. -*) -let play_until_game_result ~refuter_client ~defender_client ~rollup block = - let rec play ~player_turn ~opponent block = - let open Lwt_result_syntax in - let* game_opt = - Context.Sc_rollup.ongoing_game_for_staker - (B block) - rollup - player_turn.player.pkh - in - let game, _, _ = WithExceptions.Option.get ~loc:__LOC__ game_opt in - let* refutation = next_move ~player_client:player_turn game in - let* incr = Incremental.begin_construction block in - let* operation_refutation = - Op.sc_rollup_refute - (I incr) - player_turn.player.contract - rollup - opponent.player.pkh - (Some refutation) - in - let* incr = Incremental.add_operation incr operation_refutation in - match game_status_of_refute_op_result (Incremental.rev_tickets incr) with - | Ongoing -> - let* block = Incremental.finalize_block incr in - play ~player_turn:opponent ~opponent:player_turn block - | Ended (Loser {reason = _; loser}) as game_result -> - let () = - Format.printf - "@,ending result: %a@," - Sc_rollup.Game.pp_status - game_result - in - if loser = Account.pkh_of_contract_exn refuter_client.player.contract - then return Defender_wins - else return Refuter_wins - | Ended Draw -> - QCheck2.Test.fail_reportf "Game ended in a draw, which is unexpected" - in - play ~player_turn:refuter_client ~opponent:defender_client block - -(** Generate two {!player}s with a given strategy. *) -let make_players ~p1_strategy ~contract1 ~p2_strategy ~contract2 = - let pkh1 = Account.pkh_of_contract_exn contract1 in - let pkh2 = Account.pkh_of_contract_exn contract2 in - let ({alice; bob = _} : Game.Index.t) = Game.Index.make pkh1 pkh2 in - let player1, player2 = - if Signature.Public_key_hash.equal alice pkh1 then Game.(Alice, Bob) - else Game.(Bob, Alice) - in - ( { - pkh = pkh1; - contract = contract1; - strategy = p1_strategy; - game_player = player1; - }, - { - pkh = pkh2; - contract = contract2; - strategy = p2_strategy; - game_player = player2; - } ) - -(** [gen_game ~p1_strategy ~p2_strategy] generates a context where a rollup - was originated. - It generates inputs for the rollup, and creates the players' interpretation - of these inputs in a {!player_client} for [p1_strategy] and [p2_strategy]. -*) -let gen_game ?nonempty_inputs ~p1_strategy ~p2_strategy () = - let open QCheck2.Gen in - (* If there is no good player, we do not care about the result. *) - assert (p1_strategy = Perfect || p2_strategy = Perfect) ; - let* first_inputs = - let* input = gen_arith_pvm_inputs ~gen_size:(pure 0) in - let* inputs = small_list (gen_arith_pvm_inputs ~gen_size:(pure 0)) in - return (input :: inputs) - in - let block, rollup, genesis_info, (contract1, contract2, contract3) = - create_ctxt ~first_inputs - in - let p1, p2 = make_players ~p1_strategy ~contract1 ~p2_strategy ~contract2 in - - (* Create a context with a rollup originated. *) - let commitment_period = - Tezos_protocol_015_PtLimaPt_parameters.Default_parameters.constants_mainnet - .sc_rollup - .commitment_period_in_blocks - in - let origination_level = - Raw_level.to_int32 genesis_info.level |> Int32.to_int - in - let level_min = origination_level + 1 in - let level_max = origination_level + commitment_period - 1 in - let* levels_and_inputs = - gen_arith_pvm_inputs_for_levels ?nonempty_inputs ~level_min ~level_max () - in - let* p1_client = - Player_client.gen - ~origination_level:genesis_info.level - ~level_min - ~level_max - ~rollup - p1 - ((origination_level, first_inputs) :: levels_and_inputs) - in - let* p2_client = - Player_client.gen - ~origination_level:genesis_info.level - ~level_min - ~level_max - ~rollup - p2 - ((origination_level, first_inputs) :: levels_and_inputs) - in - let* p1_start = bool in - let commitment_level = origination_level + commitment_period in - return - ( block, - rollup, - commitment_level, - genesis_info.commitment_hash, - p1_client, - p2_client, - contract3, - p1_start, - levels_and_inputs ) - -(** [prepare_game block lcc originated_level p1_client p2_client - inputs_and_levels] prepares a context where [p1_client] and [p2_client] - are in conflict for one commitment. - It creates the protocol inbox using [inputs_and_levels]. *) -let prepare_game block rollup lcc commitment_level p1_client p2_client contract - levels_and_inputs = - let open Lwt_result_syntax in - let* block = construct_inbox_proto block rollup levels_and_inputs contract in - let* operation_publish_commitment_p1 = - operation_publish_commitment (B block) rollup lcc commitment_level p1_client - in - let* operation_publish_commitment_p2 = - operation_publish_commitment (B block) rollup lcc commitment_level p2_client - in - Block.bake - ~operations: - [operation_publish_commitment_p1; operation_publish_commitment_p2] - block - -(** Create a test of [p1_strategy] against [p2_strategy]. One of them - must be a {!Perfect} player, otherwise, we do not care about which - cheater wins. *) -let test_game ?nonempty_inputs ~p1_strategy ~p2_strategy () = - let name = - Format.asprintf - "%a against %a" - pp_strategy - p1_strategy - pp_strategy - p2_strategy - in - qcheck_make_lwt_res - ~print: - (fun ( block, - rollup, - commitment_level, - lcc, - p1_client, - p2_client, - _contract3, - p1_start, - levels_and_inputs ) -> - let level = - WithExceptions.Result.get_ok ~loc:__LOC__ @@ Context.get_level (B block) - in - Format.asprintf - "@[@,\ - current level: %a@,\ - rollup: %a@,\ - commitment_level: %d@,\ - last cemented commitment: %a@,\ - @[p1:@,\ - %a@]@,\ - @[p2:@,\ - %a@]@,\ - who start: %s@,\ - @[levels and inputs:@,\ - %a@]@,\ - @]" - Raw_level.pp - level - Sc_rollup.Address.pp_short - rollup - commitment_level - Sc_rollup.Commitment.Hash.pp_short - lcc - pp_player_client - p1_client - pp_player_client - p2_client - (if p1_start then "p1" else "p2") - pp_levels_and_inputs - levels_and_inputs) - ~count:300 - ~name - ~gen:(gen_game ?nonempty_inputs ~p1_strategy ~p2_strategy ()) - (fun ( block, - rollup, - commitment_level, - lcc, - p1_client, - p2_client, - contract3, - p1_start, - levels_and_inputs ) -> - let open Lwt_result_syntax in - (* Otherwise, there is no conflict. *) - QCheck2.assume - (not - (let p1_head = List.last_opt p1_client.states in - let p2_head = List.last_opt p2_client.states in - Option.equal - (fun (t1, state_hash1) (t2, state_hash2) -> - Tick.equal t1 t2 && State_hash.equal state_hash1 state_hash2) - p1_head - p2_head)) ; - let* block = - prepare_game - block - rollup - lcc - commitment_level - p1_client - p2_client - contract3 - levels_and_inputs - in - let refuter, defender = - if p1_start then (p1_client, p2_client) else (p2_client, p1_client) - in - let* operation_start_game = - Op.sc_rollup_refute - (B block) - refuter.player.contract - rollup - defender.player.pkh - None - in - let* block = Block.bake ~operation:operation_start_game block in - let* game_result = - play_until_game_result - ~rollup - ~refuter_client:refuter - ~defender_client:defender - block - in - match game_result with - | Defender_wins -> return (defender.player.strategy = Perfect) - | Refuter_wins -> return (refuter.player.strategy = Perfect)) - -let test_perfect_against_random = - test_game ~p1_strategy:Perfect ~p2_strategy:Random () - -let test_random_against_perfect = - test_game ~p1_strategy:Random ~p2_strategy:Perfect () - -let test_perfect_against_lazy = - test_game ~nonempty_inputs:true ~p1_strategy:Perfect ~p2_strategy:Lazy () - -let test_lazy_against_perfect = - test_game ~nonempty_inputs:true ~p1_strategy:Lazy ~p2_strategy:Perfect () - -let test_perfect_against_eager = - test_game ~nonempty_inputs:true ~p1_strategy:Perfect ~p2_strategy:Eager () - -let test_eager_against_perfect = - test_game ~nonempty_inputs:true ~p1_strategy:Eager ~p2_strategy:Perfect () - -let test_perfect_against_keen = - test_game ~p1_strategy:Perfect ~p2_strategy:Keen () - -let test_keen_against_perfect = - test_game ~p1_strategy:Keen ~p2_strategy:Perfect () - -let tests = - ( "Refutation", - qcheck_wrap - [ - test_perfect_against_random; - test_random_against_perfect; - test_perfect_against_lazy; - test_lazy_against_perfect; - test_perfect_against_eager; - test_eager_against_perfect; - test_perfect_against_keen; - test_keen_against_perfect; - ] ) - -(** {2 Entry point} *) - -let tests = [tests; Dissection.tests] - -let () = Alcotest.run "Refutation_game" tests diff --git a/src/proto_015_PtLimaPt/lib_sc_rollup/dune b/src/proto_015_PtLimaPt/lib_sc_rollup/dune deleted file mode 100644 index 0d9fe9415b43360ecfc09debf418cc6f7b01b4b0..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_sc_rollup/dune +++ /dev/null @@ -1,23 +0,0 @@ -; This file was automatically generated, do not edit. -; Edit file manifest/main.ml instead. - -(library - (name tezos_sc_rollup_015_PtLimaPt) - (public_name tezos-sc-rollup-015-PtLimaPt) - (instrumentation (backend bisect_ppx)) - (libraries - tezos-base - tezos-protocol-015-PtLimaPt - tezos-protocol-plugin-015-PtLimaPt - tezos-protocol-015-PtLimaPt.parameters - tezos-rpc) - (inline_tests (flags -verbose) (modes native)) - (preprocess (pps ppx_expect)) - (library_flags (:standard -linkall)) - (flags - (:standard) - -open Tezos_base.TzPervasives - -open Tezos_protocol_015_PtLimaPt - -open Tezos_protocol_plugin_015_PtLimaPt - -open Tezos_protocol_015_PtLimaPt_parameters - -open Tezos_rpc)) diff --git a/src/proto_015_PtLimaPt/lib_sc_rollup/game_helpers.ml b/src/proto_015_PtLimaPt/lib_sc_rollup/game_helpers.ml deleted file mode 100644 index 62038eb312ccadeb43036cd7712d4c23e477e206..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_sc_rollup/game_helpers.ml +++ /dev/null @@ -1,70 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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.Sc_rollup - -let new_dissection ~state_hash_from_tick ~default_number_of_sections - ~(start_chunk : Game.dissection_chunk) - ~(our_stop_chunk : Game.dissection_chunk) = - let open Lwt_result_syntax in - let max_number_of_sections = Z.of_int default_number_of_sections in - let trace_length = - Z.succ (Tick.distance our_stop_chunk.tick start_chunk.tick) - in - let number_of_sections = Z.min max_number_of_sections trace_length in - let rem = Z.(rem trace_length number_of_sections) in - let first_section_length, section_length = - if Compare.Z.(trace_length < max_number_of_sections) then - (* In this case, every section is of length one. *) - Z.(one, one) - else - let section_length = Z.(max one (div trace_length number_of_sections)) in - if Compare.Z.(section_length = Z.one) && not Compare.Z.(rem = Z.zero) then - (* If we put [section_length] in this situation, we will most likely - have a very long last section. *) - (rem, section_length) - else (section_length, section_length) - in - (* [k] is the number of sections in [rev_dissection]. *) - let rec make rev_dissection k tick : Game.dissection_chunk list tzresult Lwt.t - = - if Z.(equal k (pred number_of_sections)) then - return - @@ List.rev - (({ - state_hash = our_stop_chunk.state_hash; - tick = our_stop_chunk.tick; - } - : Game.dissection_chunk) - :: rev_dissection) - else - let* state_hash = state_hash_from_tick tick in - let next_tick = Tick.jump tick section_length in - make ({state_hash; tick} :: rev_dissection) (Z.succ k) next_tick - in - make - [{state_hash = start_chunk.state_hash; tick = start_chunk.tick}] - Z.one - (Tick.jump start_chunk.tick first_section_length) diff --git a/src/proto_015_PtLimaPt/lib_sc_rollup/game_helpers.mli b/src/proto_015_PtLimaPt/lib_sc_rollup/game_helpers.mli deleted file mode 100644 index ef07fc238306c99a59b4d8c5fe922feeb7e7d4fe..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_sc_rollup/game_helpers.mli +++ /dev/null @@ -1,36 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF 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.Sc_rollup - -(** Create a valid dissection based on the agreed [start_chunk] and our vision - of the stop chunk [our_stop_chunk]. We use [state_hash_from_tick] to - give our vision of the state hashes for each tick. *) -val new_dissection : - state_hash_from_tick:(Tick.t -> State_hash.t option tzresult Lwt.t) -> - default_number_of_sections:int -> - start_chunk:Game.dissection_chunk -> - our_stop_chunk:Game.dissection_chunk -> - Game.dissection_chunk list tzresult Lwt.t diff --git a/src/proto_015_PtLimaPt/lib_sc_rollup/sc_rollup_services.ml b/src/proto_015_PtLimaPt/lib_sc_rollup/sc_rollup_services.ml deleted file mode 100644 index 39f1f0626a55b26cb5b5512f03026ce895eb88c7..0000000000000000000000000000000000000000 --- a/src/proto_015_PtLimaPt/lib_sc_rollup/sc_rollup_services.ml +++ /dev/null @@ -1,255 +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_rpc -open Protocol -open Alpha_context - -(* We distinguish RPC endpoints served by the rollup node into `global` and - `local`. The difference between the two lies in whether the responses - given by different rollup nodes in the same state (see below for an - exact definition) must be the same (in the case of global endpoints) - or can differ (in the case of local endpoints). - - More formally, two rollup nodes are in the same quiescent state if they are - subscribed to the same rollup address, and have processed the same set of - heads from the layer1. We only consider quiescent states, that is those - where rollup nodes are not actively processing a head received from layer1. - - Examples of global endpoints are `current_inbox` and - `last_stored_commitment`, as the responses returned by these endpoints - is expected to be consistent across rollup nodes in the same state. - - An example of local endpoint is `last_published_commitments`, as two rollup - nodes in the same state may either publish or not publish a commitment, - according to whether its inbox level is below the inbox level of the - last cemented commitment at the time they tried to publish the commitment. - See below for a more detailed explanation. -*) - -let commitment_with_hash_and_level_encoding = - Data_encoding.( - obj3 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) - (opt "published_at_level" Raw_level.encoding)) - -module Global = struct - open RPC_path - - let prefix = root / "global" - - let sc_rollup_address () = - RPC_service.get_service - ~description:"Smart-contract rollup address" - ~query:RPC_query.empty - ~output:Sc_rollup.Address.encoding - (prefix / "sc_rollup_address") - - let current_tezos_head () = - RPC_service.get_service - ~description:"Tezos head known to the smart-contract rollup node" - ~query:RPC_query.empty - ~output:(Data_encoding.option Block_hash.encoding) - (prefix / "tezos_head") - - let current_tezos_level () = - RPC_service.get_service - ~description:"Tezos level known to the smart-contract rollup node" - ~query:RPC_query.empty - ~output:(Data_encoding.option Data_encoding.int32) - (prefix / "tezos_level") - - let current_inbox () = - RPC_service.get_service - ~description:"Current inbox" - ~query:RPC_query.empty - ~output:Sc_rollup.Inbox.encoding - (prefix / "inbox") - - let current_ticks () = - RPC_service.get_service - ~description:"Current number of ticks for current level" - ~query:RPC_query.empty - ~output:Data_encoding.z - (prefix / "ticks") - - let current_total_ticks () = - RPC_service.get_service - ~description:"Current total number of ticks" - ~query:RPC_query.empty - ~output:Sc_rollup.Tick.encoding - (prefix / "total_ticks") - - let current_num_messages () = - RPC_service.get_service - ~description:"Current number of messages" - ~query:RPC_query.empty - ~output:Data_encoding.z - (prefix / "current_num_messages") - - let current_state_hash () = - RPC_service.get_service - ~description:"Current state hash" - ~query:RPC_query.empty - ~output:Sc_rollup.State_hash.encoding - (prefix / "state_hash") - - let last_stored_commitment () = - RPC_service.get_service - ~description:"Last commitment computed by the node" - ~query:RPC_query.empty - ~output:(Data_encoding.option commitment_with_hash_and_level_encoding) - (prefix / "last_stored_commitment") - - let current_status () = - RPC_service.get_service - ~description:"Current PVM status" - ~query:RPC_query.empty - ~output:Data_encoding.string - (prefix / "status") - - let current_outbox () = - RPC_service.get_service - ~description:"Current outbox" - ~query:RPC_query.empty - ~output:Data_encoding.(list Sc_rollup.output_encoding) - (prefix / "outbox") - - let dal_slot_subscriptions () = - RPC_service.get_service - ~description:"Current data availability layer slot subscriptions" - ~query:RPC_query.empty - ~output:(Data_encoding.list Dal.Slot_index.encoding) - (prefix / "dal" / "slot_subscriptions") - - let dal_slots () = - RPC_service.get_service - ~description:"Data availability slots for a given block hash" - ~query:RPC_query.empty - ~output:(Data_encoding.list Dal.Slot.encoding) - (prefix / "dal" / "slots") - - let dal_confirmed_slots () = - RPC_service.get_service - ~description:"Data availability confirmed slots for a given block hash" - ~query:RPC_query.empty - ~output:(Data_encoding.list Dal.Slot.encoding) - (prefix / "dal" / "confirmed_slots") - - let outbox_proof_query = - let open RPC_query in - let open Sc_rollup in - let invalid_message e = - raise - (Invalid - (Format.asprintf - "Invalid message (%a)" - Environment.Error_monad.pp_trace - e)) - in - query (fun outbox_level message_index serialized_outbox_message -> - let req name f = function - | None -> - raise - (Invalid (Format.sprintf "Query parameter %s is required" name)) - | Some arg -> f arg - in - let outbox_level = - req "outbox_level" Raw_level.of_int32_exn outbox_level - in - let message_index = req "message_index" Z.of_int64 message_index in - let message = - req - "serialized_outbox_message" - (fun s -> Outbox.Message.(unsafe_of_string s |> deserialize)) - serialized_outbox_message - in - match message with - | Error e -> invalid_message e - | Ok message -> {outbox_level; message_index; message}) - |+ opt_field "outbox_level" RPC_arg.int32 (fun o -> - Some (Raw_level.to_int32 o.outbox_level)) - |+ opt_field "message_index" RPC_arg.int64 (fun o -> - Some (Z.to_int64 o.message_index)) - |+ opt_field "serialized_outbox_message" RPC_arg.string (fun o -> - match Outbox.Message.serialize o.message with - | Ok message -> Some (Outbox.Message.unsafe_to_string message) - | Error e -> invalid_message e) - |> seal - - let hex_string = - let open Data_encoding in - conv Bytes.of_string Bytes.to_string bytes - - let outbox_proof () = - RPC_service.get_service - ~description:"Generate serialized output proof for some outbox message" - ~query:outbox_proof_query - ~output: - Data_encoding.( - obj2 - (req "commitment" Sc_rollup.Commitment.Hash.encoding) - (req "proof" hex_string)) - (prefix / "proofs" / "outbox") -end - -module Local = struct - open RPC_path - - let prefix = root / "local" - - (* commitments are published only if their inbox level is above the last - cemented commitment level inbox level. Because this information is - fetched from the head of the tezos node to which the rollup node is - connected, it is possible that two rollup nodes that have processed - the same set of heads, but whose corresponding layer1 node has - different information about the last cemented commitment, will - decide to publish and not to publish a commitment, respectively. - As a consequence, the results returned by the endpoint below - in the rollup node will be different. - *) - let last_published_commitment () = - RPC_service.get_service - ~description:"Last commitment published by the node" - ~query:RPC_query.empty - ~output:(Data_encoding.option commitment_with_hash_and_level_encoding) - (prefix / "last_published_commitment") - - type state_value_query = {key : string} - - let state_value_query : state_value_query RPC_query.t = - let open RPC_query in - query (fun key -> {key}) - |+ field "key" RPC_arg.string "" (fun t -> t.key) - |> seal - - let current_state_value () = - RPC_service.get_service - ~description:"Current state value" - ~query:state_value_query - ~output:Data_encoding.bytes - RPC_path.(open_root / "state") -end