Skip to content

Commit

Permalink
Merge #2125 #2135 #2141
Browse files Browse the repository at this point in the history
2125: CLI: Add option "cardano-wallet transaction create --metadata=JSON" r=rvl a=rvl

### Issue Number

ADP-307 / #2076

### Overview

- Adds `--metadata=JSON` option to transaction create and fee estimate commands.

### Comments

Will update the CLI wiki page after merging.


2135: Fix dylib references of bundled programs on macOS r=rvl a=rvl

### Issue Number

Resolves #2134

### Overview

- On macOS rewrite dylib references from `/nix/store` to `@executable_path` - for every executable in the bundle.
- Add linking tests to `check-bundle.rb` for macOS and Linux.


2141: Make Jörmungandr tests pass again r=rvl a=piotr-iohk

# Issue Number

<!-- Put here a reference to the issue this PR relates to and which requirements it tackles -->


# Overview

- 3665332
  Disable STAKE_POOLS_* tests due to #2140
  
- 6e276af
  Remove hard-coded mnemonics in case not necessary in integration tests
  
- 038c365
  Remove Shelley specific transaction suite. Add few more basic transaction tests to Jormungandr suite.
  
- 6e98d4b
  BYRON_MIGRATE_01 - make Jormungandr big wallet for migration smaller (the same as Shelley one) and adjust to pass on both backends
  
- e3d6a55
  adjust genMnemonics to be more standard



# Comments

<!-- Additional comments or screenshots to attach if any -->

<!-- 
Don't forget to:

 ✓ Self-review your changes to make sure nothing unexpected slipped through
 ✓ Assign yourself to the PR
 ✓ Assign one or several reviewer(s)
 ✓ Once created, link this PR to its corresponding ticket
 ✓ Assign the PR to a corresponding milestone
 ✓ Acknowledge any changes required to the Wiki
-->


Co-authored-by: Rodney Lorrimar <[email protected]>
Co-authored-by: Piotr Stachyra <[email protected]>
  • Loading branch information
3 people authored Sep 17, 2020
4 parents 29a67fe + 7498249 + e43dace + e3d6a55 commit 3642da8
Show file tree
Hide file tree
Showing 20 changed files with 531 additions and 1,214 deletions.
2 changes: 2 additions & 0 deletions lib/cli/cardano-wallet-cli.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,13 @@ test-suite unit
base
, cardano-wallet-cli
, cardano-wallet-core
, containers
, filepath
, hspec
, network-uri
, optparse-applicative
, QuickCheck
, shelley-spec-ledger
, temporary
, text
, text-class
Expand Down
30 changes: 27 additions & 3 deletions lib/cli/src/Cardano/CLI.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ module Cardano.CLI
, syncToleranceOption
, tlsOption
, smashURLOption
, metadataOption

-- * Option parsers for configuring tracing
, LoggingOptions (..)
Expand Down Expand Up @@ -128,6 +129,7 @@ import Cardano.Wallet.Api.Types
, ApiPostRandomAddressData (..)
, ApiT (..)
, ApiTxId (ApiTxId)
, ApiTxMetadata (..)
, ApiWallet
, ByronWalletPostData (..)
, ByronWalletStyle (..)
Expand Down Expand Up @@ -687,6 +689,7 @@ data TransactionCreateArgs t = TransactionCreateArgs
{ _port :: Port "Wallet"
, _id :: WalletId
, _payments :: NonEmpty Text
, _metadata :: ApiTxMetadata
}

cmdTransactionCreate
Expand All @@ -702,7 +705,8 @@ cmdTransactionCreate mkTxClient mkWalletClient =
<$> portOption
<*> walletIdArgument
<*> fmap NE.fromList (some paymentOption)
exec (TransactionCreateArgs wPort wId wAddressAmounts) = do
<*> metadataOption
exec (TransactionCreateArgs wPort wId wAddressAmounts md) = do
wPayments <- either (fail . getTextDecodingError) pure $
traverse (fromText @(AddressAmount Text)) wAddressAmounts
res <- sendRequest wPort $ getWallet mkWalletClient $ ApiT wId
Expand All @@ -715,6 +719,7 @@ cmdTransactionCreate mkTxClient mkWalletClient =
(Aeson.object
[ "payments" .= wPayments
, "passphrase" .= ApiT wPwd
, "metadata" .= md
]
)
Left _ ->
Expand All @@ -733,7 +738,8 @@ cmdTransactionFees mkTxClient mkWalletClient =
<$> portOption
<*> walletIdArgument
<*> fmap NE.fromList (some paymentOption)
exec (TransactionCreateArgs wPort wId wAddressAmounts) = do
<*> metadataOption
exec (TransactionCreateArgs wPort wId wAddressAmounts md) = do
wPayments <- either (fail . getTextDecodingError) pure $
traverse (fromText @(AddressAmount Text)) wAddressAmounts
res <- sendRequest wPort $ getWallet mkWalletClient $ ApiT wId
Expand All @@ -742,7 +748,10 @@ cmdTransactionFees mkTxClient mkWalletClient =
runClient wPort Aeson.encodePretty $ postTransactionFee
mkTxClient
(ApiT wId)
(Aeson.object [ "payments" .= wPayments ])
(Aeson.object
[ "payments" .= wPayments
, "metadata" .= md
])
Left _ ->
handleResponse Aeson.encodePretty res

Expand Down Expand Up @@ -1348,6 +1357,21 @@ transactionSubmitPayloadArgument = argumentT $ mempty
<> metavar "BINARY_BLOB"
<> help "hex-encoded binary blob of externally-signed transaction."

-- | <metadata=JSON>
--
-- Note: we decode the JSON just so that we can validate more client-side.
metadataOption :: Parser ApiTxMetadata
metadataOption = option txMetadataReader $ mempty
<> long "metadata"
<> metavar "JSON"
<> value (ApiTxMetadata Nothing)
<> help ("Application-specific transaction metadata as a JSON object. "
<> "The value must match the schema defined in the "
<> "cardano-wallet OpenAPI specification.")

txMetadataReader :: ReadM ApiTxMetadata
txMetadataReader = eitherReader (Aeson.eitherDecode' . BL8.pack)

-- | <address=ADDRESS>
addressIdArgument :: Parser Text
addressIdArgument = argumentT $ mempty
Expand Down
37 changes: 36 additions & 1 deletion lib/cli/test/unit/Cardano/CLISpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import Cardano.CLI
, cmdWalletCreate
, hGetLine
, hGetSensitiveLine
, metadataOption
, smashURLOption
)
import Cardano.Wallet.Api.Client
Expand All @@ -37,6 +38,10 @@ import Cardano.Wallet.Api.Client
, transactionClient
, walletClient
)
import Cardano.Wallet.Api.Types
( ApiT (..), ApiTxMetadata (..) )
import Cardano.Wallet.Primitive.Types
( TxMetadata (..) )
import Control.Concurrent
( forkFinally )
import Control.Concurrent.MVar
Expand Down Expand Up @@ -91,8 +96,10 @@ import Test.QuickCheck
import Test.Text.Roundtrip
( textRoundtrip )

import qualified Data.Map as Map
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import qualified Shelley.Spec.Ledger.MetaData as MD

spec :: Spec
spec = do
Expand Down Expand Up @@ -262,7 +269,7 @@ spec = do

["transaction", "create", "--help"] `shouldShowUsage`
[ "Usage: transaction create [--port INT] WALLET_ID"
, " --payment PAYMENT"
, " --payment PAYMENT [--metadata JSON]"
, " Create and submit a new transaction."
, ""
, "Available options:"
Expand All @@ -272,10 +279,15 @@ spec = do
, " --payment PAYMENT address to send to and amount to send"
, " separated by @, e.g."
, " '<amount>@<address>'"
, " --metadata JSON Application-specific transaction"
, " metadata as a JSON object. The value"
, " must match the schema defined in the"
, " cardano-wallet OpenAPI specification."
]

["transaction", "fees", "--help"] `shouldShowUsage`
[ "Usage: transaction fees [--port INT] WALLET_ID --payment PAYMENT"
, " [--metadata JSON]"
, " Estimate fees for a transaction."
, ""
, "Available options:"
Expand All @@ -285,6 +297,10 @@ spec = do
, " --payment PAYMENT address to send to and amount to send"
, " separated by @, e.g."
, " '<amount>@<address>'"
, " --metadata JSON Application-specific transaction"
, " metadata as a JSON object. The value"
, " must match the schema defined in the"
, " cardano-wallet OpenAPI specification."
]

["transaction", "list", "--help"] `shouldShowUsage`
Expand Down Expand Up @@ -650,6 +666,25 @@ spec = do
, ( "relative", "/home/user", err )
]

describe "Tx Metadata JSON option" $ do
let parse arg = execParserPure defaultPrefs
(info metadataOption mempty) ["--metadata", arg]
let md = ApiT (TxMetadata (MD.MetaData (Map.singleton 42 (MD.S "hi"))))
let ok ex (Success res) = ex == getApiTxMetadata res
ok _ _ = False
let err (Failure _) = True
err _ = False
mapM_
(\(desc, arg, tst) -> it desc (parse arg `shouldSatisfy` tst))
[ ("valid", "{ \"42\": \"hi\" }", ok (Just md))
, ("malformed", "testing", err)
, ("malformed trailling", "{ \"0\": \"\" } arstneio", err)
, ("invalid", "{ \"json\": true }", err)
, ("null 1", "{ \"0\": null }", err)
, ("null 2", "null", ok Nothing)
, ("null 3", "{ }", ok (Just (ApiT mempty)))
]

where
backspace :: Text
backspace = T.singleton (toEnum 127)
Expand Down
38 changes: 34 additions & 4 deletions lib/core-integration/src/Test/Integration/Framework/DSL.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

module Test.Integration.Framework.DSL
( Context(..)
, MnemonicLength(..)
, KnownCommand(..)
, TxDescription(..)

Expand Down Expand Up @@ -62,6 +63,8 @@ module Test.Integration.Framework.DSL
, emptyWalletWith
, emptyByronWalletFromXPrvWith
, rewardWallet
, genMnemonics
, genMnemonics'
, getFromResponse
, getFromResponseList
, json
Expand Down Expand Up @@ -142,9 +145,14 @@ module Test.Integration.Framework.DSL
import Cardano.CLI
( Port (..) )
import Cardano.Mnemonic
( MkSomeMnemonic (..)
( ConsistentEntropy
, EntropySize
, MkSomeMnemonic (..)
, Mnemonic
, MnemonicWords
, SomeMnemonic (..)
, ValidChecksumSize
, ValidEntropySize
, entropyToMnemonic
, genEntropy
, mnemonicToText
Expand Down Expand Up @@ -519,6 +527,28 @@ walletId =
minUTxOValue :: Natural
minUTxOValue = 1_000_000

data MnemonicLength = M9 | M12 | M15 | M18 | M21 | M24 deriving (Show)

genMnemonics :: MnemonicLength -> IO [Text]
genMnemonics M9 = genMnemonics' @9
genMnemonics M12 = genMnemonics' @12
genMnemonics M15 = genMnemonics' @15
genMnemonics M18 = genMnemonics' @18
genMnemonics M21 = genMnemonics' @21
genMnemonics M24 = genMnemonics' @24

genMnemonics'
:: forall mw ent csz.
( ConsistentEntropy ent mw csz
, ValidEntropySize ent
, ValidChecksumSize ent csz
, ent ~ EntropySize mw
, mw ~ MnemonicWords ent
)
=> IO [Text]
genMnemonics' =
mnemonicToText . entropyToMnemonic @mw <$> genEntropy

getTxId :: (ApiTransaction n) -> String
getTxId tx = T.unpack $ toUrlPiece $ ApiTxId (tx ^. #id)

Expand Down Expand Up @@ -1642,12 +1672,12 @@ postTransactionViaCLI ctx passphrase args = do
hClose stdin
out <- TIO.hGetContents stdout
err <- TIO.hGetContents stderr
-- For some reason, when
-- - waitForProcess is called before hGetContents
-- For some reason, when
-- - waitForProcess is called before hGetContents
-- - os is windows
-- - postTransactionViaCLI was called with >= 5 outputs
-- waitForProcess blocks indefinetely. Hence we call waitForProcess
-- last.
-- last.
c <- waitForProcess h
return (c, T.unpack out, err)

Expand Down
47 changes: 3 additions & 44 deletions lib/core-integration/src/Test/Integration/Framework/TestData.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,7 @@ module Test.Integration.Framework.TestData
, invalidMnemonics15
, japaneseMnemonics12
, japaneseMnemonics15
, mnemonics3
, mnemonics6
, mnemonics9
, mnemonics12
, mnemonics15
, notInDictMnemonics15
, mnemonics18
, mnemonics21
, mnemonics24
, specMnemonicByron
, specMnemonicSentence
, specMnemonicSecondFactor
Expand Down Expand Up @@ -106,41 +98,6 @@ falseWalletIds =
, ("41 chars hex", replicate 41 '1')
]

mnemonics3 :: [Text]
mnemonics3 = ["diamond", "flee", "window"]

mnemonics6 :: [Text]
mnemonics6 = ["tornado", "canvas", "peasant", "spike", "enrich", "dilemma"]

mnemonics9 :: [Text]
mnemonics9 = ["subway", "tourist", "abstract", "roast", "border", "curious",
"exercise", "work", "narrow"]

mnemonics12 :: [Text]
mnemonics12 = ["agent", "siren", "roof", "water", "giant", "pepper",
"obtain", "oxygen", "treat", "vessel", "hip", "garlic"]

mnemonics15 :: [Text]
mnemonics15 = ["network", "empty", "cause", "mean", "expire", "private",
"finger", "accident", "session", "problem", "absurd", "banner", "stage",
"void", "what"]

mnemonics18 :: [Text]
mnemonics18 = ["whisper", "control", "diary", "solid", "cattle", "salmon",
"whale", "slender", "spread", "ice", "shock", "solve", "panel",
"caution", "upon", "scatter", "broken", "tonight"]

mnemonics21 :: [Text]
mnemonics21 = ["click", "puzzle", "athlete", "morning", "fold", "retreat",
"across", "timber", "essay", "drill", "finger", "erase", "galaxy",
"spoon", "swift", "eye", "awesome", "shrimp", "depend", "zebra", "token"]

mnemonics24 :: [Text]
mnemonics24 = ["decade", "distance", "denial", "jelly", "wash", "sword",
"olive", "perfect", "jewel", "renew", "wrestle", "cupboard", "record",
"scale", "pattern", "invite", "other", "fruit", "gloom", "west", "oak",
"deal", "seek", "hand"]

invalidMnemonics12 :: [Text]
invalidMnemonics12 = ["word","word","word","word","word","word","word",
"word","word","word","word","hill"]
Expand Down Expand Up @@ -240,7 +197,9 @@ payloadWith' name mnemonics gap = Json [json| {
simplePayload :: Payload
simplePayload = Json [json| {
"name": "Secure Wallet",
"mnemonic_sentence": #{mnemonics21},
"mnemonic_sentence": ["click", "puzzle", "athlete", "morning", "fold", "retreat",
"across", "timber", "essay", "drill", "finger", "erase", "galaxy",
"spoon", "swift", "eye", "awesome", "shrimp", "depend", "zebra", "token"],
"passphrase": #{fixturePassphrase}
} |]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ import Data.Quantity
( Quantity (..) )
import Data.Text
( Text )
import Data.Typeable
( Typeable, typeOf )
import Data.Word
( Word64 )
import Test.Hspec
Expand Down Expand Up @@ -99,6 +101,7 @@ spec :: forall n t.
, PaymentAddress n ShelleyKey
, PaymentAddress n IcarusKey
, PaymentAddress n ByronKey
, Typeable t
) => SpecWith (Context t)
spec = describe "BYRON_MIGRATIONS" $ do
it "BYRON_CALCULATE_01 - \
Expand Down Expand Up @@ -257,17 +260,23 @@ spec = describe "BYRON_MIGRATIONS" $ do
addrs <- listAddresses @n ctx wNew
let addr1 = (addrs !! 1) ^. #id

numOfTxs <- case (show (typeOf (_target ctx))) of
s | s == "Proxy * Jormungandr" -> pure 1
s | s == "Proxy * (IO Shelley)" -> pure 20
_ -> fail "unknown target backend?"

let payloadMigrate =
Json [json|
{ passphrase: #{fixturePassphrase}
, addresses: [#{addr1}]
}|]
request @[ApiTransaction n] ctx
rm <- request @[ApiTransaction n] ctx
(Link.migrateWallet @'Byron wOld)
Default
payloadMigrate >>= flip verify
payloadMigrate
verify rm
[ expectResponseCode @IO HTTP.status202
, expectField id ((`shouldBe` 20). length)
, expectField id ( (`shouldBe` (numOfTxs)) . length )
]

-- Check that funds become available in the target wallet:
Expand All @@ -284,7 +293,6 @@ spec = describe "BYRON_MIGRATIONS" $ do
(#balance . #getApiT . #total)
( `shouldBe` Quantity expectedBalance)
]

-- Analyze the target wallet UTxO distribution
request @ApiUtxoStatistics ctx (Link.getUTxOsStatistics @'Shelley wNew)
Default
Expand Down
Loading

0 comments on commit 3642da8

Please sign in to comment.