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

Fix staking integration test #220

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 3 additions & 3 deletions src/devnet/config/devnet/genesis-shelley.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
"maxTxSize": 16384,
"minFeeA": 44,
"minFeeB": 155381,
"minPoolCost": 0,
"minUTxOValue": 0,
"minPoolCost": 340000000,
"minUTxOValue": 1000000,
"nOpt": 100,
"poolDeposit": 0,
"poolDeposit": 500000000,
"protocolVersion": {
"major": 7,
"minor": 0
Expand Down
1 change: 0 additions & 1 deletion src/devnet/convex-devnet.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,3 @@ test-suite convex-devnet-test
, mtl
, aeson
, containers
, filepath
174 changes: 55 additions & 119 deletions src/devnet/lib/Convex/Devnet/CardanoNode.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,15 @@ import Control.Tracer (Tracer, traceWith)
import Convex.BuildTx (addCertificate, execBuildTx,
payToAddress)
import Convex.CoinSelection (ChangeOutputPosition (TrailingChange))
import Convex.Devnet.CardanoNode.Types (GenesisConfigChanges (..),
import Convex.Devnet.CardanoNode.Types (CardanoNodeArgs (..),
ConfigFilePath (..),
GenesisConfigChanges (..),
Port, PortsConfig (..),
RunningNode (..),
RunningStakePoolNode (..),
StakePoolNodeParams (..),
cardanoNodeProcess,
defaultCardanoNodeArgs,
defaultPortsConfig)
import qualified Convex.Devnet.NodeQueries as Q
import Convex.Devnet.Utils (checkProcessHasNotDied,
Expand Down Expand Up @@ -84,50 +88,15 @@ import System.FilePath ((</>))
import System.IO (BufferMode (NoBuffering),
hSetBuffering)
import System.Posix (ownerReadMode, setFileMode)
import System.Process (CreateProcess (..),
StdStream (UseHandle), proc,
import System.Process (CmdSpec (..),
CreateProcess (..),
StdStream (UseHandle),
readProcess,
showCommandForUser,
withCreateProcess)

import Prelude

-- | Arguments given to the 'cardano-node' command-line to run a node.
data CardanoNodeArgs = CardanoNodeArgs
{ nodeSocket :: FilePath
, nodeConfigFile :: FilePath
, nodeByronGenesisFile :: FilePath
, nodeShelleyGenesisFile :: FilePath
, nodeAlonzoGenesisFile :: FilePath
, nodeConwayGenesisFile :: FilePath
, nodeTopologyFile :: FilePath
, nodeDatabaseDir :: FilePath
, nodeDlgCertFile :: Maybe FilePath
, nodeSignKeyFile :: Maybe FilePath
, nodeOpCertFile :: Maybe FilePath
, nodeKesKeyFile :: Maybe FilePath
, nodeVrfKeyFile :: Maybe FilePath
, nodePort :: Maybe Port
}

defaultCardanoNodeArgs :: CardanoNodeArgs
defaultCardanoNodeArgs =
CardanoNodeArgs
{ nodeSocket = "node.socket"
, nodeConfigFile = "cardano-node.json"
, nodeByronGenesisFile = "genesis-byron.json"
, nodeShelleyGenesisFile = "genesis-shelley.json"
, nodeAlonzoGenesisFile = "genesis-alonzo.json"
, nodeConwayGenesisFile = "genesis-conway.json"
, nodeTopologyFile = "topology.json"
, nodeDatabaseDir = "db"
, nodeDlgCertFile = Nothing
, nodeSignKeyFile = Nothing
, nodeOpCertFile = Nothing
, nodeKesKeyFile = Nothing
, nodeVrfKeyFile = Nothing
, nodePort = Nothing
}

getCardanoNodeVersion :: IO String
getCardanoNodeVersion =
readProcess "cardano-node" ["--version"] ""
Expand All @@ -138,23 +107,29 @@ data NodeLog
| MsgCLIStatus Text Text
| MsgCLIRetry Text
| MsgCLIRetryResult Text Int
| MsgNodeStarting {stateDirectory :: FilePath}
| MsgNodeStarting {stateDirectory :: FilePath, configPath :: ConfigFilePath}
| MsgSocketIsReady FilePath
| MsgSynchronizing {percentDone :: Centi}
| MsgNodeIsReady
deriving stock (Eq, Show, Generic)
deriving anyclass (ToJSON, FromJSON)

cmdSpecString :: CmdSpec -> String
cmdSpecString = \case
ShellCommand s -> s
RawCommand fp args -> showCommandForUser fp args

withCardanoNode ::
Tracer IO NodeLog ->
NetworkId ->
ConfigFilePath ->
FilePath ->
CardanoNodeArgs ->
(RunningNode -> IO a) ->
IO a
withCardanoNode tr networkId stateDirectory args@CardanoNodeArgs{nodeSocket, nodeConfigFile} action = do
traceWith tr $ MsgNodeCmdSpec (Text.pack $ show $ cmdspec process)
traceWith tr $ MsgNodeStarting{stateDirectory}
withCardanoNode tr networkId configFilePath stateDirectory args@CardanoNodeArgs{nodeSocket, nodeConfigFile} action = do
traceWith tr $ MsgNodeCmdSpec (Text.pack $ cmdSpecString $ cmdspec process)
traceWith tr $ MsgNodeStarting{stateDirectory, configPath = configFilePath}
withLogFile logFilePath $ \out -> do
hSetBuffering out NoBuffering
withCreateProcess process{std_out = UseHandle out, std_err = UseHandle out} $
Expand All @@ -176,51 +151,13 @@ withCardanoNode tr networkId stateDirectory args@CardanoNodeArgs{nodeSocket, nod
let rnNodeConfigFile = stateDirectory </> nodeConfigFile
traceWith tr $ MsgSocketIsReady socketPath
rnConnectInfo <- runExceptT (Q.loadConnectInfo rnNodeConfigFile socketPath) >>= either (error . (<>) "Failed to load connect info: " . show) pure
let rn = RunningNode{rnNodeSocket = socketPath, rnNetworkId = networkId, rnNodeConfigFile, rnConnectInfo}
let rn = RunningNode{rnNodeSocket = socketPath, rnNetworkId = networkId, rnNodeConfigFile, rnConnectInfo, rnNodeConfigFilePath = configFilePath, rnNodeArgs = args}
action rn

cleanupSocketFile = do
x <- doesFileExist socketPath
when x (removeFile socketPath)

-- | Generate command-line arguments for launching @cardano-node@.
cardanoNodeProcess :: Maybe FilePath -> CardanoNodeArgs -> CreateProcess
cardanoNodeProcess cwd args =
(proc "cardano-node" strArgs){cwd}
where
CardanoNodeArgs
{ nodeConfigFile
, nodeTopologyFile
, nodeDatabaseDir
, nodeSocket
, nodePort
, nodeSignKeyFile
, nodeDlgCertFile
, nodeOpCertFile
, nodeKesKeyFile
, nodeVrfKeyFile
} = args

strArgs =
"run" :
mconcat
[ ["--config", nodeConfigFile]
, ["--topology", nodeTopologyFile]
, ["--database-path", nodeDatabaseDir]
, ["--socket-path", nodeSocket]
, opt "--port" (show <$> nodePort)
, opt "--byron-signing-key" nodeSignKeyFile
, opt "--byron-delegation-certificate" nodeDlgCertFile
, opt "--shelley-operational-certificate" nodeOpCertFile
, opt "--shelley-kes-key" nodeKesKeyFile
, opt "--shelley-vrf-key" nodeVrfKeyFile
]

opt :: a -> Maybe a -> [a]
opt arg = \case
Nothing -> []
Just val -> [arg, val]

-- | Wait for the node socket file to become available.
waitForSocket :: RunningNode -> IO ()
waitForSocket = waitForFile . rnNodeSocket
Expand Down Expand Up @@ -297,8 +234,8 @@ withCardanoNodeDevnet ::
FilePath ->
(RunningNode -> IO a) ->
IO a
withCardanoNodeDevnet tracer stateDirectory action =
withCardanoNodeDevnetConfig tracer stateDirectory mempty defaultPortsConfig action
withCardanoNodeDevnet tracer stateDirectory =
withCardanoNodeDevnetConfig tracer stateDirectory mempty defaultPortsConfig

-- | Start a single cardano-node devnet using the config from config/ and
-- credentials from config/credentials/. Only the 'Faucet' actor will receive
Expand All @@ -325,20 +262,21 @@ withCardanoNodeDevnetConfig tracer stateDirectory configChanges PortsConfig{ours
, "kes.skey"
, "opcert.cert"
]
let args =
defaultCardanoNodeArgs
let cfp = ConfigFilePath stateDirectory
args =
(defaultCardanoNodeArgs cfp)
{ nodeDlgCertFile = Just dlgCert
, nodeSignKeyFile = Just signKey
, nodeVrfKeyFile = Just vrfKey
, nodeKesKeyFile = Just kesKey
, nodeOpCertFile = Just opCert
, nodePort = Just ours
}
copyDevnetFiles args
copyDevnetFiles stateDirectory configChanges args
refreshSystemStart stateDirectory args
writeTopology peers stateDirectory args

withCardanoNode tracer networkId stateDirectory args $ \rn -> do
withCardanoNode tracer networkId cfp stateDirectory args $ \rn -> do
traceWith tracer MsgNodeIsReady
action rn
where
Expand All @@ -354,28 +292,29 @@ withCardanoNodeDevnetConfig tracer stateDirectory configChanges PortsConfig{ours
setFileMode destination ownerReadMode
pure destination

GenesisConfigChanges{cfAlonzo, cfConway, cfShelley, cfNodeConfig} = configChanges

copyDevnetFiles args = do
readConfigFile ("devnet" </> "cardano-node.json")
>>= copyAndChangeJSONFile
cfNodeConfig
(stateDirectory </> nodeConfigFile args)
readConfigFile ("devnet" </> "genesis-byron.json")
>>= BS.writeFile
(stateDirectory </> nodeByronGenesisFile args)
readConfigFile ("devnet" </> "genesis-shelley.json")
>>= copyAndChangeJSONFile
cfShelley
(stateDirectory </> nodeShelleyGenesisFile args)
readConfigFile ("devnet" </> "genesis-alonzo.json")
>>= copyAndChangeJSONFile
cfAlonzo
(stateDirectory </> nodeAlonzoGenesisFile args)
readConfigFile ("devnet" </> "genesis-conway.json")
>>= copyAndChangeJSONFile
cfConway
(stateDirectory </> nodeConwayGenesisFile args)
{-| Copy the devnet configuration files to the given directory
-}
copyDevnetFiles :: FilePath -> GenesisConfigChanges -> CardanoNodeArgs -> IO ()
copyDevnetFiles stateDirectory GenesisConfigChanges{cfAlonzo, cfConway, cfShelley, cfNodeConfig} args = do
readConfigFile ("devnet" </> "cardano-node.json")
>>= copyAndChangeJSONFile
cfNodeConfig
(stateDirectory </> nodeConfigFile args)
readConfigFile ("devnet" </> "genesis-byron.json")
>>= BS.writeFile
(stateDirectory </> nodeByronGenesisFile args)
readConfigFile ("devnet" </> "genesis-shelley.json")
>>= copyAndChangeJSONFile
cfShelley
(stateDirectory </> nodeShelleyGenesisFile args)
readConfigFile ("devnet" </> "genesis-alonzo.json")
>>= copyAndChangeJSONFile
cfAlonzo
(stateDirectory </> nodeAlonzoGenesisFile args)
readConfigFile ("devnet" </> "genesis-conway.json")
>>= copyAndChangeJSONFile
cfConway
(stateDirectory </> nodeConwayGenesisFile args)

writeTopology :: [Port] -> FilePath -> CardanoNodeArgs -> IO ()
writeTopology peers stateDirectory args =
Expand Down Expand Up @@ -483,16 +422,14 @@ withCardanoStakePoolNodeDevnetConfig ::
Wallet ->
-- | Stake pool params
StakePoolNodeParams ->
-- | The absolute path of the cardano-node.json configuration file
FilePath ->
-- | Ports config
PortsConfig ->
-- | Running node
RunningNode ->
-- | Action
(RunningStakePoolNode -> IO a) ->
IO a
withCardanoStakePoolNodeDevnetConfig tracer stateDirectory wallet params nodeConfigFile PortsConfig{ours, peers} node@RunningNode{rnNodeSocket, rnNetworkId} action = do
withCardanoStakePoolNodeDevnetConfig tracer stateDirectory wallet params PortsConfig{ours, peers} node@RunningNode{rnNodeSocket, rnNetworkId, rnNodeArgs, rnNodeConfigFilePath} action = do
createDirectoryIfMissing True stateDirectory

stakeKey <- C.generateSigningKey C.AsStakeKey
Expand Down Expand Up @@ -580,13 +517,13 @@ withCardanoStakePoolNodeDevnetConfig tracer stateDirectory wallet params nodeCon
delegCertTx = execBuildTx $ do
addCertificate delegationCert

_ <- W.balanceAndSubmit mempty node wallet stakeCertTx TrailingChange [C.WitnessStakeKey stakeKey]
_ <- W.balanceAndSubmit mempty node wallet stakeCertTx TrailingChange [C.WitnessStakeKey stakeKey, C.WitnessStakePoolKey stakePoolKey]
_ <- waitForNextBlock node

_ <- W.balanceAndSubmit mempty node wallet poolCertTx TrailingChange [C.WitnessStakeKey stakeKey, C.WitnessStakePoolKey stakePoolKey]
_ <- waitForNextBlock node

_ <- W.balanceAndSubmit mempty node wallet delegCertTx TrailingChange [C.WitnessStakeKey stakeKey]
_ <- W.balanceAndSubmit mempty node wallet delegCertTx TrailingChange [C.WitnessStakeKey stakeKey, C.WitnessStakePoolKey stakePoolKey]
_ <- waitForNextBlock node

vrfKeyFile <- writeEnvelope vrfKey "vrf.skey"
Expand All @@ -595,17 +532,16 @@ withCardanoStakePoolNodeDevnetConfig tracer stateDirectory wallet params nodeCon

let
args =
defaultCardanoNodeArgs
rnNodeArgs
{ nodeVrfKeyFile = Just vrfKeyFile
, nodeKesKeyFile = Just kesKeyFile
, nodeOpCertFile = Just opCertFile
, nodePort = Just ours
, nodeConfigFile = nodeConfigFile
}

writeTopology peers stateDirectory args

withCardanoNode tracer rnNetworkId stateDirectory args $ \rn -> do
withCardanoNode tracer rnNetworkId rnNodeConfigFilePath stateDirectory args $ \rn -> do
traceWith tracer MsgNodeIsReady
action (RunningStakePoolNode rn stakeKey vrfKey kesKey stakePoolKey nextOpCertCounter)
where
Expand Down
Loading
Loading