diff --git a/ci.nix b/ci.nix new file mode 100644 index 0000000..d926a80 --- /dev/null +++ b/ci.nix @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2019 Serokell +# +# SPDX-License-Identifier: MPL-2.0 + +let + sources = import nix/sources.nix; + overlay = import ./.; + nixpkgs = import sources.nixpkgs { overlays = [ overlay ]; }; +in with nixpkgs; +lib.filterAttrs (n: _: lib.hasAttr n (overlay {} {})) nixpkgs diff --git a/default.nix b/default.nix index 64653d1..5c4fdac 100644 --- a/default.nix +++ b/default.nix @@ -5,19 +5,31 @@ self: super: let - src = super.fetchFromGitHub { - owner = "ton-blockchain"; - repo = "ton"; - rev = "ac3eb1a7b86b4a5351210c4e2670e470f721b7df"; - sha256 = "1cbv14c60xmy4fanhmf9cdhj845kx6r54b8i0pljkhpv1sy74awd"; + sources = import ./nix/sources.nix; + version = builtins.substring 0 7 sources.ton.rev; + src = self.fetchFromGitHub { + inherit (sources.ton) owner repo rev; + # sadly, not the one niv comes up with. add this check + # to make sure people update the hash + sha256 = if version == "ceaed40" then + "1znikk7l2pv5mdl9rh59dljdrqkbwnazlpdjr4yfc87bcynb1rbz" else + "0000000000000000000000000000000000000000000000000000"; fetchSubmodules = true; }; - - version = "2019-09-25"; - - callPackage = super.newScope { inherit src version; }; in { - ton = callPackage ./pkgs/all.nix {}; + ton = self.callPackage ./pkgs/all.nix { inherit src version; }; + ton-vm = self.callPackage ./pkgs/vm.nix { + key = ./modules/vm/vm-ssh.key; + ports = [ 29108 29109 29110 ]; + config.imports = [ ./modules/ton.nix ]; + config.services.ton = { + enable = true; + ports.main = 29108; + ports.console = 29109; + ports.lite = 29110; + allowed_clients = { "jLl01+sOhXSANIe7kGtI/1mEYZTOf9YdzhzyDBnspVo=" = 15; }; + }; + }; } diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e36e34c --- /dev/null +++ b/flake.nix @@ -0,0 +1,35 @@ +# SPDX-FileCopyrightText: 2019 Serokell +# +# SPDX-License-Identifier: MPL-2.0 + +{ + edition = 201909; + + description = "Nix tools for the TON blockchain"; + + outputs = { self, nixpkgs }: + + let + supportedSystems = [ "x86_64-linux" "i686-linux" "aarch64-linux" ]; + forAllSystems = f: + nixpkgs.lib.genAttrs supportedSystems (system: f system); + + in { + + overlay = import ./.; + + defaultPackage = forAllSystems (system: + (import nixpkgs { + inherit system; + overlays = [ self.overlay ]; + }).ton); + + checks = + forAllSystems (system: { build = self.defaultPackage.${system}; }); + + nixosModules.ton = { + nixpkgs.overlays = [ self.overlay ]; + imports = [ ./modules/ton.nix ]; + }; + }; +} diff --git a/modules/ton.nix b/modules/ton.nix new file mode 100644 index 0000000..bfe2ba2 --- /dev/null +++ b/modules/ton.nix @@ -0,0 +1,92 @@ +# SPDX-FileCopyrightText: 2019 Serokell +# +# SPDX-License-Identifier: MPL-2.0 + +{ pkgs, lib, config, ... }: +let + cfg = config.services.ton; + server_config = { + control = [{ + id = "@SERVER_B64@"; + port = cfg.ports.console; + allowed = + lib.mapAttrsToList (id: permissions: { inherit id permissions; }) + cfg.allowed_clients; + }]; + liteservers = [{ + id = "@LITE_B64@"; + port = cfg.ports.lite; + }]; + }; + config_merge_template = + builtins.toFile "ton_config.json" (builtins.toJSON server_config); +in { + options.services.ton = with lib; { + enable = mkEnableOption "ton"; + ports.main = mkOption { + example = 29108; + type = types.port; + }; + ports.console = mkOption { + example = 29109; + type = types.port; + }; + ports.lite = mkOption { + example = 29110; + type = types.port; + }; + allowed_clients = mkOption { + example = { "jLl01+sOhXSANIe7kGtI/1mEYZTOf9YdzhzyDBnspVo=" = 15; }; + type = types.attrsOf types.int; + default = { }; + }; + }; + config = lib.mkIf cfg.enable { + environment.systemPackages = [ pkgs.ton pkgs.jq ]; + systemd.services.ton-full = { + path = with pkgs; [ ton gawk curl jq ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + DynamicUser = true; + StateDirectory = "ton"; + RuntimeDirectory = "ton"; + Type = "simple"; + WorkingDirectory = "/var/lib/ton"; + ExecStart = + "${pkgs.ton}/bin/validator-engine -C /var/lib/ton/etc/ton-global.config.json --db /var/lib/ton/db"; + }; + environment.HOME = "/var/lib/ton"; + # see https://test.ton.org/FullNode-HOWTO.txt + preStart = '' + mkdir -p etc db db/keyring + if [ ! -e etc/ton-global.config.json ]; then + curl https://test.ton.org/ton-global.config.json > etc/ton-global.config.json + fi + IP=$(curl https://ifconfig.me) + rm -f db/config.json + validator-engine -C $HOME/etc/ton-global.config.json --db $HOME/db --ip $IP:${ + toString cfg.ports.main + } + if [ ! -e server_id ]; then + echo "generating server key" + generate-random-id -m keys -n server | tee server_id + mv server db/keyring/$(awk '{print $1}' server_id) + fi + SERVER_B64=$(awk '{print $2}' server_id) + echo "server key | base64:" + base64 server.pub + if [ ! -e lite_id ]; then + generate-random-id -m keys -n lite | tee lite_id + mv lite db/keyring/$(awk '{print $1}' lite_id) + fi + echo "lite key | base64:" + base64 lite.pub + LITE_B64=$(awk '{print $2}' lite_id) + cp server.pub lite.pub /run/ton + sed -e "s/@SERVER_B64@/$SERVER_B64/g" -e "s/@LITE_B64@/$LITE_B64/g" < ${config_merge_template} > config_merge.json + mv db/config.json config_generated.json + jq -s '.[0] * .[1]' config_generated.json config_merge.json > db/config.json + ''; + }; + }; +} diff --git a/modules/vm/vm-ssh.key b/modules/vm/vm-ssh.key new file mode 100644 index 0000000..6839b14 --- /dev/null +++ b/modules/vm/vm-ssh.key @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +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 +-----END OPENSSH PRIVATE KEY----- diff --git a/modules/vm/vm-ssh.key.pub b/modules/vm/vm-ssh.key.pub new file mode 100644 index 0000000..2520cd6 --- /dev/null +++ b/modules/vm/vm-ssh.key.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC6Zq/FXQbmURQVlmdFKMqWaxa8C43VoP4NnMrEiCYrZPljZZQLjtlfYg66UGCP+MDrLdfEQNwx32a4OdotP9MvAS7/R6qHwtuMHcObh/4wTi0uRC0LCUw8O07qmz+vDzKm8iLmohHmh8yo/1JLxLom1hNKi1S320koiZSIhzlAlr+WuHVYJlmQk9Ei+03jXxj4BX5rdCFQ9rDjceapRPlApeisqlOK0B6567hc0WYXKXCraPlTnwVf0A1+AWApU4NHq3PRtO6LtfESVp+Vt4VkDdTCpspF3G12Ss7RLwnZAjhSSD+DNj4YMIwYOz47OzgO6I/LnAq3BwOsd4AHYH8pFr+k+37Gw9Z2MzqG4yB8qLXG1iIKt3mwVn8bjmlTMb4Gb1Ohu2qCpduxZlGkGYOGwOfHm0aRmBu4il7TKhZsktaQUCpkyJcezrUnBQi+Bee/gFZCdtpu8paheBeyaJOdEiZNs++yO4i1sTMKshYSKWz6dQW9UoNO/jUVRr+Klz0= yorick@jarvis.yori.cc diff --git a/nix/sources.json b/nix/sources.json new file mode 100644 index 0000000..49fb62d --- /dev/null +++ b/nix/sources.json @@ -0,0 +1,38 @@ +{ + "niv": { + "branch": "master", + "description": "Easy dependency management for Nix projects", + "homepage": "https://github.com/nmattia/niv", + "owner": "nmattia", + "repo": "niv", + "rev": "444c1ad4896ace10b97ab5becede1ceeced0a90c", + "sha256": "199nhdwlnk4wn4kgqyjq9z5cwlajjq7j3i4f54ihc1l9b9rggfd8", + "type": "tarball", + "url": "https://github.com/nmattia/niv/archive/444c1ad4896ace10b97ab5becede1ceeced0a90c.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, + "nixpkgs": { + "branch": "nixos-19.09", + "description": "A read-only mirror of NixOS/nixpkgs tracking the released channels. Send issues and PRs to", + "homepage": "https://github.com/NixOS/nixpkgs", + "owner": "NixOS", + "repo": "nixpkgs-channels", + "rev": "131ff6dd9c8dc64dc7e0c4ece49782dbf54bff83", + "sha256": "012513794dvpg4kdwmyj4a04vgz56w9k1y9jp3c81f3zwzrclqha", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs-channels/archive/131ff6dd9c8dc64dc7e0c4ece49782dbf54bff83.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, + "ton": { + "branch": "master", + "description": null, + "homepage": null, + "owner": "ton-blockchain", + "repo": "ton", + "rev": "ceaed40ac4871ffaeb5b493586ab6f0899fd490d", + "sha256": "1p3kg2l7h6nfnjizf0xgs7090037v60zz8qmqamvf9y71ic9cr7f", + "type": "tarball", + "url": "https://github.com/ton-blockchain/ton/archive/ceaed40ac4871ffaeb5b493586ab6f0899fd490d.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + } +} diff --git a/nix/sources.nix b/nix/sources.nix new file mode 100644 index 0000000..d4ac577 --- /dev/null +++ b/nix/sources.nix @@ -0,0 +1,93 @@ +# This file has been generated by Niv. + +# A record, from name to path, of the third-party packages +with rec +{ + pkgs = + if hasNixpkgsPath + then + if hasThisAsNixpkgsPath + then import (builtins_fetchTarball { inherit (sources_nixpkgs) url sha256; }) {} + else import {} + else + import (builtins_fetchTarball { inherit (sources_nixpkgs) url sha256; }) {}; + + sources_nixpkgs = + if builtins.hasAttr "nixpkgs" sources + then sources.nixpkgs + else abort + '' + Please specify either (through -I or NIX_PATH=nixpkgs=...) or + add a package called "nixpkgs" to your sources.json. + ''; + + # fetchTarball version that is compatible between all the versions of Nix + builtins_fetchTarball = + { url, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchTarball; + in + if lessThan nixVersion "1.12" then + fetchTarball { inherit url; } + else + fetchTarball attrs; + + # fetchurl version that is compatible between all the versions of Nix + builtins_fetchurl = + { url, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchurl; + in + if lessThan nixVersion "1.12" then + fetchurl { inherit url; } + else + fetchurl attrs; + + # A wrapper around pkgs.fetchzip that has inspectable arguments, + # annoyingly this means we have to specify them + fetchzip = { url, sha256 }@attrs: pkgs.fetchzip attrs; + + # A wrapper around pkgs.fetchurl that has inspectable arguments, + # annoyingly this means we have to specify them + fetchurl = { url, sha256 }@attrs: pkgs.fetchurl attrs; + + hasNixpkgsPath = (builtins.tryEval ).success; + hasThisAsNixpkgsPath = + (builtins.tryEval ).success && == ./.; + + sources = builtins.fromJSON (builtins.readFile ./sources.json); + + mapAttrs = builtins.mapAttrs or + (f: set: with builtins; + listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))); + + # borrowed from nixpkgs + functionArgs = f: f.__functionArgs or (builtins.functionArgs f); + callFunctionWith = autoArgs: f: args: + let auto = builtins.intersectAttrs (functionArgs f) autoArgs; + in f (auto // args); + + getFetcher = spec: + let fetcherName = + if builtins.hasAttr "type" spec + then builtins.getAttr "type" spec + else "builtin-tarball"; + in builtins.getAttr fetcherName { + "tarball" = fetchzip; + "builtin-tarball" = builtins_fetchTarball; + "file" = fetchurl; + "builtin-url" = builtins_fetchurl; + }; +}; +# NOTE: spec must _not_ have an "outPath" attribute +mapAttrs (_: spec: + if builtins.hasAttr "outPath" spec + then abort + "The values in sources.json should not have an 'outPath' attribute" + else + if builtins.hasAttr "url" spec && builtins.hasAttr "sha256" spec + then + spec // + { outPath = callFunctionWith spec (getFetcher spec) { }; } + else spec + ) sources diff --git a/pkgs/all.nix b/pkgs/all.nix index eb67837..598d697 100644 --- a/pkgs/all.nix +++ b/pkgs/all.nix @@ -7,18 +7,16 @@ , stdenv, lib , cmake, pkgconfig , openssl, readline, zlib +, libmicrohttpd }: stdenv.mkDerivation rec { pname = "ton"; - inherit version; - name = "${pname}-${version}"; - - inherit src; + inherit version src; patches = [ ./patches/tonlib-cmake-config.patch ./patches/install-binaries.patch ]; nativeBuildInputs = [ cmake pkgconfig ]; - buildInputs = [ openssl readline zlib ]; + buildInputs = [ openssl readline zlib libmicrohttpd ]; } diff --git a/pkgs/patches/install-binaries.patch b/pkgs/patches/install-binaries.patch index 594ff08..788c027 100644 --- a/pkgs/patches/install-binaries.patch +++ b/pkgs/patches/install-binaries.patch @@ -2,22 +2,6 @@ # # SPDX-License-Identifier: LGPL-2.0-or-later -diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt -index c76de70..382303d 100644 ---- a/crypto/CMakeLists.txt -+++ b/crypto/CMakeLists.txt -@@ -333,3 +333,11 @@ target_link_libraries(dump-block PUBLIC ton_crypto fift-lib ton_block) - if (WINGETOPT_FOUND) - target_link_libraries_system(dump-block wingetopt) - endif() -+ -+ -+install(TARGETS fift func tlbc create-state dump-block -+ LIBRARY DESTINATION lib -+ ARCHIVE DESTINATION lib -+ RUNTIME DESTINATION bin -+ INCLUDES DESTINATION include -+) diff --git a/lite-client/CMakeLists.txt b/lite-client/CMakeLists.txt index a1afd52..f45dac2 100644 --- a/lite-client/CMakeLists.txt diff --git a/pkgs/vm.nix b/pkgs/vm.nix new file mode 100644 index 0000000..548c6c3 --- /dev/null +++ b/pkgs/vm.nix @@ -0,0 +1,56 @@ +{ nixos, lib, path, writeShellScriptBin, config, key, ports ? [ ] }: +let hostfwd = lib.concatMapStrings (a: ",hostfwd=tcp::${toString a}-:${toString a}") ports; +in (nixos { + imports = [ "${path}/nixos/modules/virtualisation/qemu-vm.nix" config ]; + services.openssh.enable = true; + networking.firewall.allowedTCPPorts = ports; + # install the vm-ssh.key.pub for ssh access + users.users.root.openssh.authorizedKeys.keyFiles = [ "${toString key}.pub" ]; + services.mingetty = { + autologinUser = "root"; + helpLine = '' + ssh access: + ./result/bin/ssh + update running system (does not survive reboot): + nix-build -A vm && ./result/bin/switch-running-vm + to get out: + poweroff + ''; + }; + # qemu settings: + virtualisation = { + memorySize = 1024; + diskSize = 1024; + # set up serial console + graphics = false; + qemu = { + options = [ "-serial mon:stdio" ]; + # forward port 22 to 2222 and port 80 to 8080 + # based on the default in nixpkgs + networkingOptions = [ + "-net nic,netdev=user.0,model=virtio" + "-netdev user,id=user.0,hostfwd=tcp::2222-:22${hostfwd}\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}" + ]; + }; + }; + +}).config.system.build.vm.overrideAttrs (old: + let + # add switch-running-vm, ssh scripts + ssh = writeShellScriptBin "ssh" '' + set -e + ssh -o StrictHostKeyChecking=no -i ${ + toString key + } root@localhost -p 2222 "$@" + ''; + switch-running-vm = writeShellScriptBin "switch-running-vm" '' + set -e + $(dirname "$0")/ssh $(realpath $(dirname "$0"))/../system/bin/switch-to-configuration test + ''; + in { + buildCommand = old.buildCommand + '' + ln -s ${switch-running-vm}/bin/* $out/bin/ + ln -s ${ssh}/bin/* $out/bin/ + ''; + }) +