Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement optional block authentication #27

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
implement optional block authentication
larskuhtz committed Mar 23, 2023

Verified

This commit was signed with the committer’s verified signature.
larskuhtz Lars Kuhtz
commit 6a5e00a4367967f01b29f2b5058b89018e9edfd3
10 changes: 9 additions & 1 deletion cabal.project
Original file line number Diff line number Diff line change
@@ -2,7 +2,15 @@ packages: .
allow-newer:
streaming-events:*

package hashes
extra-include-dirs:
/opt/local/include
/usr/local/opt/openssl/include
extra-lib-dirs:
/opt/local/lib
/usr/local/opt/openssl/lib/

source-repository-package
type: git
location: https://github.com/kadena-io/deeproute.git
tag: 856be917bf162a769d9082c26700af4bdbb87d49
tag: 856be917bf162a769d9082c26700af4bdbb87d49
2 changes: 2 additions & 0 deletions chainweb-mining-client.cabal
Original file line number Diff line number Diff line change
@@ -84,6 +84,7 @@ executable chainweb-mining-client
, deeproute:deeproute-wai
, exceptions >=0.10
, hashable >=1.3
, hashes >=0.2.3
, hostaddress >=0.2
, http-client >=0.7
, http-client-tls >=0.3
@@ -137,6 +138,7 @@ test-suite tests
, cryptonite >=0.27
, exceptions >=0.10
, hashable >=1.3
, hashes >=0.2.3
, hostaddress >=0.2
, memory >=0.15
, quickcheck-instances >=0.3
41 changes: 35 additions & 6 deletions main/Main.hs
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
@@ -42,6 +43,7 @@ import Control.Retry
import Crypto.Hash.Algorithms (Blake2s_256)
import qualified Crypto.PubKey.Ed25519 as C

import Data.Bifunctor
import qualified Data.ByteArray.Encoding as BA
import Data.Bytes.Get
import Data.Bytes.Put
@@ -90,6 +92,7 @@ import Worker.External
import Worker.ConstantDelay
import Worker.SimulatedMiner
import Worker.OnDemand
import WorkerUtils
import qualified Worker.POW.Stratum as Stratum
import qualified Worker.POW.Stratum.Server as Stratum

@@ -262,6 +265,7 @@ data Config = Config
, _configOnDemandPort :: !Port
, _configOnDemandInterface :: !HostPreference
, _configConstantDelayBlockTime :: !Natural
, _configBlockAuthenticationKey :: !(Maybe BlockAuthenticationKey)
}
deriving (Show, Eq, Ord, Generic)

@@ -287,6 +291,7 @@ defaultConfig = Config
, _configOnDemandPort = 1917
, _configOnDemandInterface = "*"
, _configConstantDelayBlockTime = 30
, _configBlockAuthenticationKey = Nothing
}

instance ToJSON Config where
@@ -309,6 +314,7 @@ instance ToJSON Config where
, "onDemandPort" .= _configOnDemandPort c
, "onDemandInterface" .= _configOnDemandInterface c
, "constantDelayBlockTime" .= _configConstantDelayBlockTime c
, "BlockAuthenticationKey" .= _configBlockAuthenticationKey c
]

instance FromJSON (Config -> Config) where
@@ -331,6 +337,7 @@ instance FromJSON (Config -> Config) where
<*< configOnDemandPort ..: "onDemandPort" % o
<*< configOnDemandInterface ..: "onDemandInterface" % o
<*< configConstantDelayBlockTime ..: "constantDelayBlockTime" % o
<*< configBlockAuthenticationKey ..: "blockAuthenticationKey" % o
where
parseLogLevel = withText "LogLevel" $ return . logLevelFromText

@@ -403,6 +410,14 @@ parseConfig = id
<*< configOnDemandPort .:: option jsonReader
% long "on-demand-port"
<> help "port on which the on-demand mining server listens"
<*< configBlockAuthenticationKey .:: fmap Just . option (eitherReader $ first T.unpack . readBlockAuthenticationKeyHex . T.pack)
% long "block-authentication-key"
<> help "if provided non-PoW miners and the CPU miner authenticate the nonce with this key"
<> metavar "HEX[32]"

validateConfig :: ConfigValidation Config []
validateConfig _c = do
return ()

-- -------------------------------------------------------------------------- --
-- HTTP Retry Logic
@@ -793,8 +808,8 @@ genKeys = do
-- -------------------------------------------------------------------------- --
-- Main

mainInfo :: ProgramInfo Config
mainInfo = programInfo "Kadena Chainweb Mining Client" parseConfig defaultConfig
mainInfo :: ProgramInfoValidate Config []
mainInfo = programInfoValidate "Kadena Chainweb Mining Client" parseConfig defaultConfig validateConfig

-- | TODO: validate the configuration:
--
@@ -827,17 +842,31 @@ run conf logger = do

workerRate = _getUnitPrefixed (_configHashRate conf) / fromIntegral (_configThreadCount conf)

maybeKey = _configBlockAuthenticationKey conf

-- provide the inner computation with an initialized worker
withWorker f = case _configWorker conf of

-- Non-PoW Workers

SimulatedMinerWorker -> do
rng <- MWC.createSystemRandom
f $ \l -> simulatedMinerWorker l rng workerRate
f $ \l -> simulatedMinerWorker l rng workerRate maybeKey

ConstantDelayWorker -> do
f $ \l -> constantDelayWorker l (_configConstantDelayBlockTime conf)
f $ \l -> constantDelayWorker l (_configConstantDelayBlockTime conf) maybeKey

OnDemandWorker -> do
withOnDemandWorker logger (_configOnDemandPort conf) (_configOnDemandInterface conf) f
withOnDemandWorker logger (_configOnDemandPort conf) (_configOnDemandInterface conf) maybeKey f

-- PoW Workers

ExternalWorker -> f $ \l -> externalWorker l (_configExternalWorkerCommand conf)
CpuWorker -> f $ cpuWorker @Blake2s_256

CpuWorker -> case maybeKey of
Nothing -> f $ cpuWorker @Blake2s_256
Just key -> f $ authenticatedCpuWorker @Blake2s_256 key

StratumWorker -> Stratum.withStratumServer
logger
(_configStratumPort conf)
11 changes: 8 additions & 3 deletions src/Worker/ConstantDelay.hs
Original file line number Diff line number Diff line change
@@ -29,18 +29,23 @@ import System.LogLevel

import Logger
import Worker
import WorkerUtils

-- -------------------------------------------------------------------------- --
-- Simulation Mining Worker

-- | A mining worker that is not actually doing any work. It returns the work
-- bytes unchanged after a configured time delay passes.
--
constantDelayWorker :: Logger -> Natural -> Worker
constantDelayWorker logger delay _nonce _target _cid work = do
constantDelayWorker
:: Logger
-> Natural
-> Maybe BlockAuthenticationKey
-> Worker
constantDelayWorker logger delay key _nonce _target _cid work = do
logg Info $ "solve time (seconds): " <> T.pack (show delay)
threadDelay ((1_000000 * fromIntegral delay) `div` 20)
return work
return $! authenticateWork key work
where
logg = writeLog logger

16 changes: 11 additions & 5 deletions src/Worker/OnDemand.hs
Original file line number Diff line number Diff line change
@@ -44,16 +44,18 @@ import qualified System.LogLevel as L

import Logger
import Worker
import WorkerUtils

withOnDemandWorker
:: Logger
-> Port
-> HostPreference
-> Maybe BlockAuthenticationKey
-> ((Logger -> Worker) -> IO ())
-> IO ()
withOnDemandWorker logger port host inner = do
withOnDemandWorker logger port host key inner = do
miningGoals <- newTVarIO (HashMap.empty @ChainId @Word)
race (server miningGoals) (inner (worker miningGoals)) >>= \case
race (server miningGoals) (inner (worker miningGoals key)) >>= \case
Left _ -> writeLog logger L.Error "server exited unexpectedly"
Right _ -> writeLog logger L.Error "mining loop exited unexpectedly"
where
@@ -66,11 +68,15 @@ withOnDemandWorker logger port host inner = do
& Warp.setPort (fromIntegral port)
& Warp.setHost host

worker :: TVar (HashMap ChainId Word) -> Logger -> Worker
worker goalsRef minerLogger _nonce _target cid work = do
worker
:: TVar (HashMap ChainId Word)
-> Maybe BlockAuthenticationKey
-> Logger
-> Worker
worker goalsRef key minerLogger _nonce _target cid work = do
atomically $ do
goals <- readTVar goalsRef
guard (any (/= 0) goals)
writeTVar goalsRef (HashMap.adjust (\g -> if g == 0 then 0 else pred g) cid goals)
writeLog minerLogger L.Info $ "block demanded for chain " <> T.pack (show cid)
return work
return $! authenticateWork key work
Loading