Skip to content

Commit

Permalink
Scaffold simple Cardano client interface
Browse files Browse the repository at this point in the history
* Computes a payment address from a verification key
* Simplifies submit_test.sh script remove call to compute address
  • Loading branch information
abailly-iohk committed Oct 18, 2021
1 parent 7ed9c79 commit 511af95
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 11 deletions.
5 changes: 3 additions & 2 deletions hydra-node/test/Hydra/Chain/DirectSpec.hs
Expand Up @@ -8,6 +8,7 @@ module Hydra.Chain.DirectSpec where
import Hydra.Prelude
import Test.Hydra.Prelude

import CardanoCluster (ClusterConfig (..))
import Control.Concurrent (newEmptyMVar, putMVar, takeMVar)
import Hydra.Chain (
Chain (..),
Expand All @@ -25,13 +26,13 @@ import Hydra.Party (Party, deriveParty, generateKey)
import Test.QuickCheck (generate)

spec :: Spec
spec = parallel $ do
spec = do
it "can init and abort a head given nothing has been committed" $ do
calledBackAlice <- newEmptyMVar
calledBackBob <- newEmptyMVar
aliceKeys@(aliceVk, _) <- generateKeyPair
bobKeys@(bobVk, _) <- generateKeyPair
withMockServer $ \networkMagic iocp socket submitTx -> do
withCluster tracer config $ \(ClusterConfig clusterDirectory) -> do
withDirectChain nullTracer networkMagic iocp socket aliceKeys (putMVar calledBackAlice) $ \Chain{postTx} -> do
withDirectChain nullTracer networkMagic iocp socket bobKeys (putMVar calledBackBob) $ \_ -> do
let parameters = HeadParameters 100 [alice, bob, carol]
Expand Down
8 changes: 7 additions & 1 deletion local-cluster/local-cluster.cabal
@@ -1,4 +1,4 @@
cabal-version: 2.2
cabal-version: 3.0
name: local-cluster
version: 0.1.0
synopsis:
Expand Down Expand Up @@ -71,6 +71,7 @@ library
import: project-config
hs-source-dirs: src
exposed-modules:
CardanoClient
CardanoCluster
CardanoNode
Hydra.Generator
Expand All @@ -83,7 +84,9 @@ library
, base >=4.7 && <5
, bytestring
, cardano-api
, cardano-cli
, cardano-crypto-class
, cardano-ledger-core
, containers
, contra-tracer
, directory
Expand Down Expand Up @@ -152,6 +155,7 @@ test-suite integration
other-modules:
Paths_local_cluster
Spec
Test.CardanoClientSpec
Test.DirectChainSpec
Test.EndToEndSpec
Test.GeneratorSpec
Expand All @@ -165,8 +169,10 @@ test-suite integration
, bytestring
, cardano-api
, cardano-crypto-class
, cardano-ledger-core
, containers
, filepath
, hedgehog-quickcheck
, hspec
, hspec-core
, hydra-node
Expand Down
28 changes: 28 additions & 0 deletions local-cluster/src/CardanoClient.hs
@@ -0,0 +1,28 @@
-- | A basic cardano-node client that can talk to a local cardano-node.
--
-- The idea of this module is to provide a Haskell interface on top of cardano-cli's API.
module CardanoClient where

import Hydra.Prelude

import Cardano.Api (Address, NetworkId, ShelleyAddr)
import Cardano.Api.Shelley (VerificationKey (PaymentVerificationKey))
import Cardano.CLI.Shelley.Run.Address (buildShelleyAddress)
import qualified Cardano.Ledger.Keys as Keys
import qualified Hydra.Chain.Direct.Wallet as Hydra

type NodeSocket = FilePath

-- | Build an address give a key.
-- From <runAddressBuild https://github.com/input-output-hk/cardano-node/blob/master/cardano-cli/src/Cardano/CLI/Shelley/Run/Address.hs#L106>
buildAddress :: Hydra.VerificationKey -> NetworkId -> IO (Address ShelleyAddr)
buildAddress vKey networkId = do
let shelleyKey = PaymentVerificationKey $ Keys.VKey vKey
runExceptT (buildShelleyAddress shelleyKey Nothing networkId) >>= \case
Left err -> throwIO $ BuildAddressException (show err)
Right addr -> pure addr

newtype BuildAddressException = BuildAddressException Text
deriving (Show)

instance Exception BuildAddressException
18 changes: 18 additions & 0 deletions local-cluster/test/Test/CardanoClientSpec.hs
@@ -0,0 +1,18 @@
module Test.CardanoClientSpec where

import Cardano.Api (NetworkId (Testnet), NetworkMagic (NetworkMagic))
import qualified Cardano.Ledger.Keys as Ledger
import CardanoClient (buildAddress)
import Hydra.Ledger.Cardano (genKeyPair)
import Hydra.Prelude
import Test.Hydra.Prelude
import Test.QuickCheck.Monadic (PropertyM, forAllM, monadicIO, run)

spec :: Spec
spec = do
prop "can generate address from verification key" $ monadicIO generateAddressFromKey

generateAddressFromKey :: PropertyM IO ()
generateAddressFromKey =
forAllM genKeyPair $ \(Ledger.KeyPair (Ledger.VKey key) _) -> do
void $ run $ buildAddress key (Testnet $ NetworkMagic 42)
17 changes: 11 additions & 6 deletions local-cluster/test/Test/LocalClusterSpec.hs
Expand Up @@ -3,8 +3,11 @@ module Test.LocalClusterSpec where
import Hydra.Prelude
import Test.Hydra.Prelude

import CardanoCluster (ClusterConfig (..), ClusterLog (..), RunningCluster (..), testClusterConfig, withCluster)
import Cardano.Api (Address, ShelleyAddr, serialiseToBech32)
import CardanoClient (buildAddress)
import CardanoCluster (ClusterConfig (..), ClusterLog (..), RunningCluster (..), keysFor, testClusterConfig, withCluster)
import CardanoNode (ChainTip (..), RunningNode (..), cliQueryTip)
import Data.Text (unpack)
import Hydra.Logging (Tracer, showLogsOnFailure)
import qualified Paths_local_cluster as Pkg
import System.Environment (getEnvironment)
Expand Down Expand Up @@ -37,13 +40,15 @@ assertNetworkIsProducingBlock tracer = go (-1)

assertCanSpendInitialFunds :: HasCallStack => RunningCluster -> IO ()
assertCanSpendInitialFunds = \case
RunningCluster (ClusterConfig parentDirectory _) (RunningNode nodeId socket : _) ->
runTestScript (parentDirectory </> "node-" <> show nodeId) socket
cluster@(RunningCluster ClusterConfig{parentStateDirectory, networkId} (RunningNode nodeId socket : _)) -> do
(vk, _) <- keysFor "alice" cluster
addr <- buildAddress vk networkId
runTestScript (parentStateDirectory </> "node-" <> show nodeId) addr socket
_ ->
error "empty cluster?"

runTestScript :: FilePath -> FilePath -> IO ()
runTestScript nodeDirectory socket = do
runTestScript :: FilePath -> Address ShelleyAddr -> FilePath -> IO ()
runTestScript nodeDirectory addr socket = do
inputScript <- Pkg.getDataFileName "test_submit.sh"
currentEnv <- getEnvironment
let scriptOutput = nodeDirectory </> "test_submit.out"
Expand All @@ -55,7 +60,7 @@ runTestScript nodeDirectory socket = do
where
socketEnv = ("CARDANO_NODE_SOCKET_PATH", socket)
sh baseEnv script out =
(proc "/bin/sh" [script])
(proc "/bin/sh" [script, unpack $ serialiseToBech32 addr])
{ env = Just (socketEnv : baseEnv)
, cwd = Just nodeDirectory
, std_out = UseHandle out
Expand Down
5 changes: 3 additions & 2 deletions local-cluster/test_submit.sh
Expand Up @@ -5,7 +5,8 @@ set -vx

[ -x $(which cardano-cli) ] || { echo "cardano-cli not found, check PATH environment variable" ; exit 1 ; }

utxo_addr=$(cardano-cli address build --payment-verification-key-file utxo1.vkey --testnet-magic 42)
utxo_addr=$1

transfer_amount=100000000

# take first utxo available
Expand All @@ -25,7 +26,7 @@ cardano-cli transaction build-raw --tx-in $utxo \
--tx-out $utxo_addr+$(($amount - $transfer_amount - $fees)) \
--invalid-hereafter $((slot + 100)) --fee $fees --out-file tx.draft

cardano-cli transaction sign --tx-body-file tx.draft --signing-key-file utxo1.skey --testnet-magic 42 --out-file tx.signed
cardano-cli transaction sign --tx-body-file tx.draft --signing-key-file ../alice.sk --testnet-magic 42 --out-file tx.signed
cardano-cli transaction submit --tx-file tx.signed --testnet-magic 42

timeout=30
Expand Down

0 comments on commit 511af95

Please sign in to comment.