diff --git a/hschain-utxo-pow-node/CHANGELOG.md b/hschain-utxo-pow-node/CHANGELOG.md new file mode 100644 index 00000000..3ab19f25 --- /dev/null +++ b/hschain-utxo-pow-node/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for hschain-utxo + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/hschain-utxo-pow-node/LICENSE b/hschain-utxo-pow-node/LICENSE new file mode 100644 index 00000000..e037c729 --- /dev/null +++ b/hschain-utxo-pow-node/LICENSE @@ -0,0 +1,30 @@ +Copyright Author name here (c) 2018 + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Author name here nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/hschain-utxo-pow-node/Setup.hs b/hschain-utxo-pow-node/Setup.hs new file mode 100644 index 00000000..9a994af6 --- /dev/null +++ b/hschain-utxo-pow-node/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/hschain-utxo-pow-node/app/Genesis.hs b/hschain-utxo-pow-node/app/Genesis.hs new file mode 100644 index 00000000..21cdd281 --- /dev/null +++ b/hschain-utxo-pow-node/app/Genesis.hs @@ -0,0 +1,54 @@ +-- | Generates initial genesis with all funds owned by single user. +module Main where + +import Data.Aeson.Encode.Pretty +import Data.Aeson +import Data.Default +import Data.Fix + +import Hschain.Utxo.Lang +import Hschain.Utxo.Lang.Build + +import Data.ByteString.Char8 as B +import Data.ByteString.Lazy as LB +import Data.ByteString.Char8 as LB +import qualified Data.Map.Strict as M +import qualified Data.Vector as V + +main :: IO () +main = B.putStrLn . LB.toStrict . encodePretty =<< singleOwnerGenesis + +singleOwnerGenesis :: IO [Tx] +singleOwnerGenesis = withSecret =<< newSecret + where + withSecret secret = do + Right proof <- newProof env (Fix $ SigmaPk publicKey) + return $ [tx proof] + where + publicKey = getPublicKey secret + env = proofEnvFromKeys [getKeyPair secret] + + box = Box + { box'id = BoxId "master:box-0" + , box'value = initMoney + , box'script = toScript $ pk' publicKey + , box'args = M.empty + } + + tx proof = Tx + { tx'inputs = V.empty + , tx'outputs = V.fromList [box] + , tx'proof = Just proof + , tx'args = mempty + } + + initMoney = 1000000 + + + + + + + + + diff --git a/hschain-utxo-pow-node/app/Main.hs b/hschain-utxo-pow-node/app/Main.hs new file mode 100644 index 00000000..34c1eabd --- /dev/null +++ b/hschain-utxo-pow-node/app/Main.hs @@ -0,0 +1,7 @@ +module Main where + +import Hschain.Utxo.App + +main :: IO () +main = runApp + diff --git a/hschain-utxo-pow-node/config/main/node-val1.yaml b/hschain-utxo-pow-node/config/main/node-val1.yaml new file mode 100644 index 00000000..afcc5d5f --- /dev/null +++ b/hschain-utxo-pow-node/config/main/node-val1.yaml @@ -0,0 +1,20 @@ +port : "45001" +seeds : + - "127.0.0.1:45002" + - "127.0.0.1:45003" + - "127.0.0.1:45004" +privKey : "2K7bFuJXxKf5LqogvVRQjms2W26ZrjpvUjo5LdvPFa5Y" +validators: + - "HVQNfbH8rj2uVb6XyC41wzGCMGVFooeBZJMLnRBJifTX" + - "HUs35FXTSYA3zY39MrKjqFdeCvTxx97uccPFxvwpqgt7" + - "AZ3m8VUkPJ8iGNgQ5zpG4rMBqg5VNAYtSaJDmrR4Rz1m" + - "2PggMrWVjsvUvrZHqYVgH4PRpjVp2oYJe9gjaWrU1R4m" +dbName : "/var/run/user/1000/db/node-1" +logs: + files : + - type : "ScribeJSON" + path : "logs/node-1.log" + severity : "Debug" + verbosity : "V2" + namespace: "validator-node1" + diff --git a/hschain-utxo-pow-node/config/main/node-val2.yaml b/hschain-utxo-pow-node/config/main/node-val2.yaml new file mode 100644 index 00000000..42c2d879 --- /dev/null +++ b/hschain-utxo-pow-node/config/main/node-val2.yaml @@ -0,0 +1,19 @@ +port : "45002" +seeds : + - "127.0.0.1:45003" + - "127.0.0.1:45004" +privKey : "4NSWtMsEPgfTK25tCPWqNzVVze1dgMwcUFwS5WkSpjJL" +validators: + - "HVQNfbH8rj2uVb6XyC41wzGCMGVFooeBZJMLnRBJifTX" + - "HUs35FXTSYA3zY39MrKjqFdeCvTxx97uccPFxvwpqgt7" + - "AZ3m8VUkPJ8iGNgQ5zpG4rMBqg5VNAYtSaJDmrR4Rz1m" + - "2PggMrWVjsvUvrZHqYVgH4PRpjVp2oYJe9gjaWrU1R4m" +dbName : "/var/run/user/1000/db/node-2" +logs: + files : + - type : "ScribeJSON" + path : "logs/node-2.log" + severity : "Debug" + verbosity : "V2" + namespace: "validator-node2" + diff --git a/hschain-utxo-pow-node/config/main/node-val3.yaml b/hschain-utxo-pow-node/config/main/node-val3.yaml new file mode 100644 index 00000000..b1bb760e --- /dev/null +++ b/hschain-utxo-pow-node/config/main/node-val3.yaml @@ -0,0 +1,18 @@ +port : "45003" +seeds : + - "127.0.0.1:45004" +privKey : "3Fj8bZjKc53F2a87sQaFkrDas2d9gjzK57FmQwnNnSHS" +validators: + - "HVQNfbH8rj2uVb6XyC41wzGCMGVFooeBZJMLnRBJifTX" + - "HUs35FXTSYA3zY39MrKjqFdeCvTxx97uccPFxvwpqgt7" + - "AZ3m8VUkPJ8iGNgQ5zpG4rMBqg5VNAYtSaJDmrR4Rz1m" + - "2PggMrWVjsvUvrZHqYVgH4PRpjVp2oYJe9gjaWrU1R4m" +dbName : "/var/run/user/1000/db/node-3" +logs: + files : + - type : "ScribeJSON" + path : "logs/node-3.log" + severity : "Debug" + verbosity : "V2" + namespace: "validator-node3" + diff --git a/hschain-utxo-pow-node/config/main/node-val4.yaml b/hschain-utxo-pow-node/config/main/node-val4.yaml new file mode 100644 index 00000000..ce1bccb5 --- /dev/null +++ b/hschain-utxo-pow-node/config/main/node-val4.yaml @@ -0,0 +1,17 @@ +port : "45004" +seeds : [] +privKey : "D2fpHM1JA8trshiUW8XPvspsapUvPqVzSofaK1MGRySd" +validators: + #- "HVQNfbH8rj2uVb6XyC41wzGCMGVFooeBZJMLnRBJifTX" + # - "HUs35FXTSYA3zY39MrKjqFdeCvTxx97uccPFxvwpqgt7" + # - "AZ3m8VUkPJ8iGNgQ5zpG4rMBqg5VNAYtSaJDmrR4Rz1m" + - "2PggMrWVjsvUvrZHqYVgH4PRpjVp2oYJe9gjaWrU1R4m" +dbName : "/var/run/user/1000/db/node-4" +logs: + files : + - type : "ScribeJSON" + path : "logs/node-4.log" + severity : "Debug" + verbosity : "V2" + namespace: "validator-node4" + diff --git a/hschain-utxo-pow-node/config/main/node-web.yaml b/hschain-utxo-pow-node/config/main/node-web.yaml new file mode 100644 index 00000000..d24fac7a --- /dev/null +++ b/hschain-utxo-pow-node/config/main/node-web.yaml @@ -0,0 +1,23 @@ +server: + host: 127.0.0.1 + port: 8080 +node: + port: "45000" + seeds: + - "127.0.0.1:45001" + - "127.0.0.1:45002" + - "127.0.0.1:45003" + - "127.0.0.1:45004" + validators: + - "HVQNfbH8rj2uVb6XyC41wzGCMGVFooeBZJMLnRBJifTX" + - "HUs35FXTSYA3zY39MrKjqFdeCvTxx97uccPFxvwpqgt7" + - "AZ3m8VUkPJ8iGNgQ5zpG4rMBqg5VNAYtSaJDmrR4Rz1m" + - "2PggMrWVjsvUvrZHqYVgH4PRpjVp2oYJe9gjaWrU1R4m" + dbName : "/var/run/user/1000/db/node-web" + logs: + files : + - type : "ScribeJSON" + severity : "Debug" + path : "logs/node-web.log" + verbosity : "V2" + namespace: "node-web" diff --git a/hschain-utxo-pow-node/config/pool/genesis.json b/hschain-utxo-pow-node/config/pool/genesis.json new file mode 100644 index 00000000..61754b8e --- /dev/null +++ b/hschain-utxo-pow-node/config/pool/genesis.json @@ -0,0 +1,14 @@ +[ + { + "args": {}, + "inputs": [], + "outputs": [ + { + "script": "pk \"2zYxFt1frN27gKPHoQNfEHt5e7AqSUkLQ5kZ1b9a2cPxWzV\"", + "args": {}, + "value": 1000000, + "id": "master:box-0" + } + ] + } +] diff --git a/hschain-utxo-pow-node/hschain-utxo-pow-node.cabal b/hschain-utxo-pow-node/hschain-utxo-pow-node.cabal new file mode 100644 index 00000000..4e83e56f --- /dev/null +++ b/hschain-utxo-pow-node/hschain-utxo-pow-node.cabal @@ -0,0 +1,68 @@ +cabal-version: >=1.10 +name: hschain-utxo +version: 0.1.0.0 +synopsis: Useful utils for hschain-utxo (generation of genesis) +-- description: +-- bug-reports: +-- license: +license-file: LICENSE +author: anton-k +maintainer: anton.kholomiov@gmail.com +-- copyright: +-- category: +build-type: Simple +extra-source-files: CHANGELOG.md + +library + exposed-modules: Hschain.Utxo.App + Hschain.Utxo.App.Options + -- other-modules: + -- other-extensions: + build-depends: base >=4.11 && <5 + , hex-common + , hschain-utxo-lang + , hschain-utxo-service + , optparse-applicative + hs-source-dirs: src + default-language: Haskell2010 + default-extensions: + DataKinds + DeriveGeneric + GeneralizedNewtypeDeriving + LambdaCase + MultiParamTypeClasses + TypeFamilies + OverloadedStrings + RecordWildCards + ScopedTypeVariables + StandaloneDeriving + TemplateHaskell + + +executable hschain-utxo-pow-node-app + main-is: Main.hs + -- other-modules: + -- other-extensions: + build-depends: base >=4.11 && <5 + , hschain-utxo + hs-source-dirs: app + default-language: Haskell2010 + +executable hschain-utxo-pow-generate-genesis + main-is: Genesis.hs + -- other-modules: + -- other-extensions: + build-depends: base >=4.11 && <5 + , aeson + , aeson-pretty + , bytestring + , containers + , data-default + , data-fix + , hschain-utxo-lang + , vector + hs-source-dirs: app + default-language: Haskell2010 + default-extensions: + OverloadedStrings + diff --git a/hschain-utxo-pow-node/src/Hschain/Utxo/App.hs b/hschain-utxo-pow-node/src/Hschain/Utxo/App.hs new file mode 100644 index 00000000..3d2cc64b --- /dev/null +++ b/hschain-utxo-pow-node/src/Hschain/Utxo/App.hs @@ -0,0 +1,33 @@ +module Hschain.Utxo.App( + runApp +) where + +import Hex.Common.Aeson +import Hex.Common.Yaml + +import Control.Monad + +import Data.Maybe + +import Hschain.Utxo.Lang +import Hschain.Utxo.Back.App +import Hschain.Utxo.App.Options + +runApp :: IO () +runApp = app =<< readOptions + +app :: Options -> IO () +app = \case + RunWebNode{..} -> runBy runWebNode runWebNode'config runWebNode'genesis + RunValidator{..} -> runBy runValidator runValidator'config runValidator'genesis + where + runBy :: (FromJSON a, Show a) => (a -> [Tx] -> IO ()) -> FilePath -> FilePath -> IO () + runBy cmd configPath genesisPath = + join $ cmd <$> readYaml configPath <*> readGenesis genesisPath + + readGenesis :: FilePath -> IO [Tx] + readGenesis = fmap (fromMaybe err) . readJson + where + err = error "Error: failed to read genesis" + + diff --git a/hschain-utxo-pow-node/src/Hschain/Utxo/App/Options.hs b/hschain-utxo-pow-node/src/Hschain/Utxo/App/Options.hs new file mode 100644 index 00000000..781a8835 --- /dev/null +++ b/hschain-utxo-pow-node/src/Hschain/Utxo/App/Options.hs @@ -0,0 +1,48 @@ +module Hschain.Utxo.App.Options( + Options(..) + , readOptions +) where + +import Options.Applicative + +readOptions :: IO Options +readOptions = execParser opts + where + opts = info (options <**> helper) + ( fullDesc + <> progDesc "Utility to run webnodes and validators" + <> header "hschain-utxo - utility to run webnodes and validators" ) + +data Options + = RunWebNode + { runWebNode'config :: FilePath + , runWebNode'genesis :: FilePath + } + | RunValidator + { runValidator'config :: FilePath + , runValidator'genesis :: FilePath + } + +options :: Parser Options +options = subparser + ( command "webnode" webnodeParser + <> command "validator" validatorParser + ) + where + webnodeParser = configParser RunWebNode "Run webnode" + validatorParser = configParser RunValidator "Run validator" + + configParser cons msg = info parser (progDesc msg) + where + parser = cons + <$> strOption + ( metavar "CONFIG_FILE_PATH" + <> long "config" + <> short 'c' + <> help "path to config") + <*> strOption + ( metavar "GENESIS_FILE_PATH" + <> long "genesis" + <> short 'g' + <> help "path to genesis") +