Skip to content

Commit 7344c78

Browse files
Support registration certificates
1 parent 1e09173 commit 7344c78

File tree

9 files changed

+92
-53
lines changed

9 files changed

+92
-53
lines changed

cardano-node-emulator/cardano-node-emulator.cabal

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ test-suite cardano-node-emulator-test
126126
-- Other IOG dependencies
127127
--------------------------
128128
build-depends:
129-
, cardano-api
130-
, plutus-ledger-api >=1.0.0
131-
, plutus-tx >=1.0.0
132-
, plutus-tx-plugin >=1.0.0
129+
, cardano-api:{cardano-api, gen, internal}
130+
, plutus-ledger-api >=1.0.0
131+
, plutus-tx >=1.0.0
132+
, plutus-tx-plugin >=1.0.0
133133

134134
------------------------
135135
-- Non-IOG dependencies

cardano-node-emulator/src/Cardano/Node/Emulator/API.hs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,17 @@ import Ledger (
8282
DatumHash,
8383
DecoratedTxOut,
8484
POSIXTime,
85-
PaymentPrivateKey (unPaymentPrivateKey),
85+
PaymentPrivateKey,
8686
Slot,
8787
TxOutRef,
8888
UtxoIndex,
8989
)
90+
import Ledger.Address (toWitness)
9091
import Ledger.AddressMap qualified as AM
9192
import Ledger.Index qualified as Index
9293
import Ledger.Tx (
9394
TxOut,
94-
addCardanoTxSignature,
95+
addCardanoTxWitness,
9596
cardanoTxOutValue,
9697
getCardanoTxData,
9798
getCardanoTxId,
@@ -262,13 +263,13 @@ balanceTx utxoIndex changeAddr utx = do
262263
-- | Sign a transaction with the given signatures.
263264
signTx
264265
:: (MonadEmulator m, Foldable f)
265-
=> f PaymentPrivateKey
266+
=> f C.ShelleyWitnessSigningKey
266267
-- ^ Signatures
267268
-> CardanoTx
268269
-> m CardanoTx
269-
signTx keys tx = do
270+
signTx witnesses tx = do
270271
logMsg L.Info $ TxBalanceMsg $ SigningTx tx
271-
pure $ foldr (addCardanoTxSignature . unPaymentPrivateKey) tx keys
272+
pure $ foldr addCardanoTxWitness tx witnesses
272273

273274
-- | Balance a transaction, sign it with the given signatures, and finally queue it.
274275
submitUnbalancedTx
@@ -277,13 +278,13 @@ submitUnbalancedTx
277278
-- ^ Just the transaction inputs, not the entire 'UTxO'.
278279
-> CardanoAddress
279280
-- ^ Wallet address
280-
-> f PaymentPrivateKey
281+
-> f C.ShelleyWitnessSigningKey
281282
-- ^ Signatures
282283
-> CardanoBuildTx
283284
-> m CardanoTx
284-
submitUnbalancedTx utxoIndex changeAddr keys utx = do
285+
submitUnbalancedTx utxoIndex changeAddr witnesses utx = do
285286
newTx <- balanceTx utxoIndex changeAddr utx
286-
signedTx <- signTx keys newTx
287+
signedTx <- signTx witnesses newTx
287288
queueTx signedTx
288289
pure signedTx
289290

@@ -293,12 +294,12 @@ submitTxConfirmed
293294
-- ^ Just the transaction inputs, not the entire 'UTxO'.
294295
-> CardanoAddress
295296
-- ^ Wallet address
296-
-> f PaymentPrivateKey
297+
-> f C.ShelleyWitnessSigningKey
297298
-- ^ Signatures
298299
-> CardanoBuildTx
299300
-> m CardanoTx
300-
submitTxConfirmed utxoIndex addr privateKeys utx = do
301-
tx <- submitUnbalancedTx utxoIndex addr privateKeys utx
301+
submitTxConfirmed utxoIndex addr witnesses utx = do
302+
tx <- submitUnbalancedTx utxoIndex addr witnesses utx
302303
nextSlot
303304
pure tx
304305

@@ -311,7 +312,7 @@ payToAddress (sourceAddr, sourcePrivKey) targetAddr value = do
311312
G.emptyTxBodyContent
312313
{ C.txOuts = [C.TxOut targetAddr (toCardanoTxOutValue value) C.TxOutDatumNone C.ReferenceScriptNone]
313314
}
314-
getCardanoTxId <$> submitUnbalancedTx mempty sourceAddr [sourcePrivKey] buildTx
315+
getCardanoTxId <$> submitUnbalancedTx mempty sourceAddr [toWitness sourcePrivKey] buildTx
315316

316317
-- | Log any message
317318
logMsg :: (MonadEmulator m) => L.LogLevel -> EmulatorMsg -> m ()

cardano-node-emulator/src/Cardano/Node/Emulator/Generators.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,11 @@ import Ledger (
102102
ValidationErrorInPhase,
103103
ValidationPhase (Phase1, Phase2),
104104
ValidationResult (FailPhase1, FailPhase2),
105-
addCardanoTxSignature,
105+
addCardanoTxWitness,
106106
createGenesisTransaction,
107107
minLovelaceTxOutEstimated,
108108
pubKeyAddress,
109+
toWitness,
109110
txOutValue,
110111
)
111112
import Ledger.CardanoWallet qualified as CW
@@ -123,8 +124,8 @@ import Test.Gen.Cardano.Api.Typed qualified as Gen
123124
-- | Attach signatures of all known private keys to a transaction.
124125
signAll :: CardanoTx -> CardanoTx
125126
signAll tx =
126-
foldl' (flip addCardanoTxSignature) tx $
127-
fmap unPaymentPrivateKey CW.knownPaymentPrivateKeys
127+
foldl' (flip addCardanoTxWitness) tx $
128+
fmap toWitness CW.knownPaymentPrivateKeys
128129

129130
-- | The parameters for the generators in this module.
130131
data GeneratorModel = GeneratorModel

cardano-node-emulator/src/Cardano/Node/Emulator/Internal/Node/Fee.hs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import Cardano.Api.Fees (mapTxScriptWitnesses)
2525
import Cardano.Api.Shelley qualified as C
2626
import Cardano.Api.Shelley qualified as C.Api
2727
import Cardano.Ledger.BaseTypes (Globals (systemStart), epochInfo)
28+
import Cardano.Ledger.Shelley.TxCert (shelleyTotalDepositsTxCerts)
2829
import Cardano.Node.Emulator.Internal.Node.Params (
2930
EmulatorEra,
3031
Params (emulatorPParams),
@@ -34,6 +35,7 @@ import Cardano.Node.Emulator.Internal.Node.Params (
3435
)
3536
import Cardano.Node.Emulator.Internal.Node.Validation (
3637
CardanoLedgerError,
38+
Coin (unCoin),
3739
UTxO (UTxO),
3840
createAndValidateTransactionBody,
3941
getTxExUnitsWithLogs,
@@ -248,8 +250,14 @@ handleBalanceTx params (C.UTxO txUtxo) cChangeAddr utxoProvider errorReporter fe
248250

249251
inputValues <- traverse lookupValue txInputs
250252

251-
let left = Tx.getTxBodyContentMint filteredUnbalancedTxTx <> fold inputValues
252-
right = lovelaceToValue fees <> foldMap (Tx.txOutValue . Tx.TxOut) (C.txOuts filteredUnbalancedTxTx)
253+
let pp = emulatorPParams params
254+
txDeposits = shelleyTotalDepositsTxCerts pp (const False) (Tx.getTxBodyContentCerts utx)
255+
coinToValue = lovelaceToValue . C.Lovelace . unCoin
256+
left = Tx.getTxBodyContentMint filteredUnbalancedTxTx <> fold inputValues
257+
right =
258+
lovelaceToValue fees
259+
<> foldMap (Tx.txOutValue . Tx.TxOut) (C.txOuts filteredUnbalancedTxTx)
260+
<> coinToValue txDeposits
253261
balance = left <> C.negateValue right
254262

255263
((neg, newInputs), (pos, mNewTxOut)) <-

cardano-node-emulator/test/Cardano/Node/Emulator/MTLSpec.hs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,8 @@
22

33
module Cardano.Node.Emulator.MTLSpec (tests) where
44

5-
import Control.Monad (void)
6-
import Data.Map qualified as Map
7-
import Data.Text.Lazy qualified as LText
8-
import Data.Text.Lazy.Encoding qualified as Text
9-
import Ledger.Address (CardanoAddress, PaymentPrivateKey)
10-
import Ledger.Tx.CardanoAPI (CardanoBuildTx (CardanoBuildTx))
11-
import Ledger.Value.CardanoAPI qualified as Value
12-
import Test.Tasty (TestTree, testGroup)
13-
import Test.Tasty.Golden (goldenVsString)
14-
5+
import Cardano.Api qualified as C
6+
import Cardano.Api.Address qualified as C
157
import Cardano.Node.Emulator.API (
168
nextSlot,
179
payToAddress,
@@ -26,13 +18,23 @@ import Cardano.Node.Emulator.Test (
2618
renderLogs,
2719
runEmulatorM,
2820
)
21+
import Control.Monad (void)
22+
import Data.Map qualified as Map
23+
import Data.Text.Lazy qualified as LText
24+
import Data.Text.Lazy.Encoding qualified as Text
25+
import Ledger.Address (CardanoAddress, PaymentPrivateKey, toWitness, unPaymentPubKeyHash)
26+
import Ledger.CardanoWallet (knownMockWallet, paymentPubKeyHash)
27+
import Ledger.Tx.CardanoAPI (CardanoBuildTx (CardanoBuildTx), toCardanoStakeKeyHash)
28+
import Ledger.Value.CardanoAPI qualified as Value
29+
import Test.Tasty (TestTree, testGroup)
30+
import Test.Tasty.Golden (goldenVsString)
2931

3032
tests :: TestTree
3133
tests =
3234
testGroup
3335
"Cardano.Node.Emulator.MTL"
3436
[ checkPredicateOptions options "submit empty tx" (hasValidatedTransactionCountOfTotal 1 1) $ do
35-
void $ submitUnbalancedTx mempty w1 [pk1] (CardanoBuildTx E.emptyTxBodyContent)
37+
void $ submitUnbalancedTx mempty w1 [toWitness pk1] (CardanoBuildTx E.emptyTxBodyContent)
3638
nextSlot
3739
, checkPredicateOptions options "payToAddress" (hasValidatedTransactionCountOfTotal 1 1) $ do
3840
void $ payToAddress (w1, pk1) w2 (Value.adaValueOf 1)
@@ -59,6 +61,19 @@ tests =
5961
void $ payToAddress (w1, pk1) w2 (Value.adaValueOf 1)
6062
nextSlot
6163
)
64+
, checkPredicateOptions options "submit staking tx" (hasValidatedTransactionCountOfTotal 1 1) $ do
65+
let
66+
Right stakeKeyHash = toCardanoStakeKeyHash . unPaymentPubKeyHash . paymentPubKeyHash $ knownMockWallet 1
67+
stakeCred = C.StakeCredentialByKey stakeKeyHash
68+
stakeCert =
69+
C.makeStakeAddressRegistrationCertificate
70+
(C.StakeAddrRegistrationPreConway C.ShelleyToBabbageEraBabbage stakeCred)
71+
tx =
72+
E.emptyTxBodyContent
73+
{ C.txCertificates = C.TxCertificates C.shelleyBasedEra [stakeCert] (C.BuildTxWith mempty)
74+
}
75+
void $ submitUnbalancedTx mempty w1 [toWitness pk1] (CardanoBuildTx tx)
76+
nextSlot
6277
]
6378

6479
w1, w2 :: CardanoAddress

cardano-node-emulator/test/Plutus/Examples/Escrow.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import Cardano.Node.Emulator.Test (testnet)
7070
import Data.Maybe (fromJust)
7171
import Ledger (POSIXTime, PaymentPubKeyHash (unPaymentPubKeyHash), TxId, getCardanoTxId)
7272
import Ledger qualified
73+
import Ledger.Address (toWitness)
7374
import Ledger.Tx.CardanoAPI qualified as C
7475
import Ledger.Typed.Scripts (validatorCardanoAddress)
7576
import Ledger.Typed.Scripts qualified as Scripts
@@ -300,7 +301,7 @@ pay wallet privateKey escrow vl = do
300301
E.logInfo @String $ "Pay " <> show vl <> " to the script"
301302
slotConfig <- asks pSlotConfig
302303
let (utx, utxoIndex) = mkPayTx slotConfig escrow wallet vl
303-
void $ E.submitTxConfirmed utxoIndex wallet [privateKey] utx
304+
void $ E.submitTxConfirmed utxoIndex wallet [toWitness privateKey] utx
304305

305306
newtype RedeemSuccess = RedeemSuccess TxId
306307
deriving (Eq, Show)
@@ -355,7 +356,7 @@ redeem
355356
redeem wallet privateKey escrow = do
356357
E.logInfo @String "Redeeming"
357358
(utx, utxoIndex) <- mkRedeemTx escrow
358-
RedeemSuccess . getCardanoTxId <$> E.submitTxConfirmed utxoIndex wallet [privateKey] utx
359+
RedeemSuccess . getCardanoTxId <$> E.submitTxConfirmed utxoIndex wallet [toWitness privateKey] utx
359360

360361
newtype RefundSuccess = RefundSuccess TxId
361362
deriving newtype (Eq, Show)
@@ -408,7 +409,7 @@ refund
408409
refund wallet privateKey escrow = do
409410
E.logInfo @String "Refunding"
410411
(utx, utxoIndex) <- mkRefundTx escrow wallet
411-
RefundSuccess . getCardanoTxId <$> E.submitTxConfirmed utxoIndex wallet [privateKey] utx
412+
RefundSuccess . getCardanoTxId <$> E.submitTxConfirmed utxoIndex wallet [toWitness privateKey] utx
412413

413414
-- Submit a transaction attempting to take the refund belonging to the given pk.
414415
mkBadRefundTx
@@ -449,7 +450,7 @@ badRefund
449450
badRefund wallet privateKey escrow pkh = do
450451
E.logInfo @String "Bad refund"
451452
(utx, utxoIndex) <- mkBadRefundTx escrow pkh
452-
(void $ E.submitTxConfirmed utxoIndex wallet [privateKey] utx)
453+
(void $ E.submitTxConfirmed utxoIndex wallet [toWitness privateKey] utx)
453454
`catchError` (\err -> E.logError $ "Caught error: " ++ show err)
454455

455456
{- | Pay some money into the escrow contract. Then release all funds to their

cardano-node-emulator/test/Plutus/Examples/Game.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import Data.ByteString.Char8 qualified as C
3030
import Data.Map qualified as Map
3131
import GHC.Generics (Generic)
3232
import Ledger (CardanoAddress, POSIXTime, PaymentPrivateKey, UtxoIndex, Validator, getValidator)
33-
import Ledger.Address (mkValidatorCardanoAddress)
33+
import Ledger.Address (mkValidatorCardanoAddress, toWitness)
3434
import Ledger.Tx.CardanoAPI qualified as C
3535
import Ledger.Typed.Scripts qualified as Scripts
3636
import Plutus.Script.Utils.Typed (ScriptContextV2, Versioned)
@@ -168,11 +168,11 @@ submitLockTx :: (E.MonadEmulator m) => CardanoAddress -> PaymentPrivateKey -> Lo
168168
submitLockTx wallet privateKey lockArgs@LockArgs{lockArgsValue} = do
169169
E.logInfo @String $ "Pay " <> show lockArgsValue <> " to the script"
170170
let (utx, utxoIndex) = mkLockTx lockArgs
171-
void $ E.submitTxConfirmed utxoIndex wallet [privateKey] utx
171+
void $ E.submitTxConfirmed utxoIndex wallet [toWitness privateKey] utx
172172

173173
submitGuessTx :: (E.MonadEmulator m) => CardanoAddress -> PaymentPrivateKey -> GuessArgs -> m ()
174174
submitGuessTx wallet privateKey guessArgs@GuessArgs{guessArgsGameParam} = do
175175
E.logInfo @String "Taking a guess"
176176
utxos <- E.utxosAt (mkGameAddress guessArgsGameParam)
177177
let (utx, utxoIndex) = mkGuessTx utxos guessArgs
178-
void $ E.submitTxConfirmed utxoIndex wallet [privateKey] utx
178+
void $ E.submitTxConfirmed utxoIndex wallet [toWitness privateKey] utx

plutus-ledger/src/Ledger/Address.hs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ module Ledger.Address (
1111
PaymentPrivateKey (..),
1212
PaymentPubKey (..),
1313
PaymentPubKeyHash (..),
14+
StakePrivateKey (..),
1415
StakePubKey (..),
1516
StakePubKeyHash (..),
17+
ToWitness (..),
1618
toPlutusAddress,
1719
toPlutusPubKeyHash,
1820
cardanoAddressCredential,
@@ -143,6 +145,8 @@ makeLift ''PaymentPubKeyHash
143145
xprvToPaymentPubKeyHash :: Crypto.XPrv -> PaymentPubKeyHash
144146
xprvToPaymentPubKeyHash = PaymentPubKeyHash . pubKeyHash . toPublicKey
145147

148+
newtype StakePrivateKey = StakePrivateKey {unStakePrivateKey :: Crypto.XPrv}
149+
146150
newtype StakePubKey = StakePubKey {unStakePubKey :: PubKey}
147151
deriving stock (Eq, Ord, Generic)
148152
deriving anyclass (ToJSON, FromJSON, ToJSONKey, FromJSONKey)
@@ -214,3 +218,12 @@ stakePubKeyHashCredential = StakingHash . PubKeyCredential . unStakePubKeyHash
214218
-- | Construct a `StakingCredential` from a validator script hash.
215219
stakeValidatorHashCredential :: StakeValidatorHash -> StakingCredential
216220
stakeValidatorHashCredential (StakeValidatorHash h) = StakingHash . ScriptCredential . ScriptHash $ h
221+
222+
class ToWitness a where
223+
toWitness :: a -> C.ShelleyWitnessSigningKey
224+
225+
instance ToWitness PaymentPrivateKey where
226+
toWitness (PaymentPrivateKey xprv) = C.WitnessPaymentExtendedKey (C.PaymentExtendedSigningKey xprv)
227+
228+
instance ToWitness StakePrivateKey where
229+
toWitness (StakePrivateKey xprv) = C.WitnessStakeExtendedKey (C.StakeExtendedSigningKey xprv)

plutus-ledger/src/Ledger/Tx.hs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,14 @@ module Ledger.Tx (
6969
getCardanoTxData,
7070
CardanoTx (.., CardanoEmulatorEraTx),
7171
ToCardanoError (..),
72-
addCardanoTxSignature,
72+
addCardanoTxWitness,
7373

7474
-- * TxBodyContent functions
7575
getTxBodyContentInputs,
7676
getTxBodyContentCollateralInputs,
7777
getTxBodyContentReturnCollateral,
7878
getTxBodyContentMint,
79+
getTxBodyContentCerts,
7980
txBodyContentIns,
8081
txBodyContentCollateralIns,
8182
txBodyContentOuts,
@@ -86,8 +87,8 @@ module Ledger.Tx (
8687
) where
8788

8889
import Cardano.Api qualified as C
90+
import Cardano.Api.ReexposeLedger qualified as C.Ledger
8991
import Cardano.Api.Shelley qualified as C.Api
90-
import Cardano.Crypto.Wallet qualified as Crypto
9192
import Cardano.Ledger.Alonzo.Tx (AlonzoTx (..))
9293
import Cardano.Ledger.Alonzo.TxWits (txwitsVKey)
9394
import Codec.Serialise (Serialise)
@@ -452,6 +453,11 @@ getCardanoTxValidityRange (CardanoTx (C.Tx (C.TxBody C.TxBodyContent{..}) _) _)
452453
getCardanoTxData :: CardanoTx -> Map V1.DatumHash V1.Datum
453454
getCardanoTxData (CardanoTx (C.Tx txBody _) _) = fst $ CardanoAPI.scriptDataFromCardanoTxBody txBody
454455

456+
getTxBodyContentCerts :: C.TxBodyContent ctx era -> [C.Ledger.TxCert (C.Api.ShelleyLedgerEra era)]
457+
getTxBodyContentCerts C.TxBodyContent{..} = case txCertificates of
458+
C.TxCertificatesNone -> mempty
459+
C.TxCertificates _ certs _ -> C.Api.toShelleyCertificate <$> certs
460+
455461
-- TODO: add txMetaData
456462

457463
txBodyContentIns
@@ -484,28 +490,22 @@ getCardanoTxExtraKeyWitnesses (CardanoEmulatorEraTx (C.Tx (C.TxBody C.TxBodyCont
484490
C.Api.TxExtraKeyWitnessesNone -> mempty
485491
C.Api.TxExtraKeyWitnesses _ txwits -> txwits
486492

487-
type PrivateKey = Crypto.XPrv
488-
489-
addCardanoTxSignature :: PrivateKey -> CardanoTx -> CardanoTx
490-
addCardanoTxSignature privKey = addSignatureCardano
493+
addCardanoTxWitness :: C.Api.ShelleyWitnessSigningKey -> CardanoTx -> CardanoTx
494+
addCardanoTxWitness witness (CardanoEmulatorEraTx ctx) = CardanoEmulatorEraTx (addWitness ctx)
491495
where
492-
addSignatureCardano :: CardanoTx -> CardanoTx
493-
addSignatureCardano (CardanoEmulatorEraTx ctx) =
494-
CardanoEmulatorEraTx (addSignatureCardano' ctx)
495-
496-
addSignatureCardano' (C.Api.ShelleyTx shelleyBasedEra (AlonzoTx body wits isValid aux)) =
496+
addWitness (C.Api.ShelleyTx shelleyBasedEra (AlonzoTx body wits isValid aux)) =
497497
C.Api.ShelleyTx shelleyBasedEra (AlonzoTx body wits' isValid aux)
498498
where
499499
wits' = wits <> mempty{txwitsVKey = newWits}
500-
newWits = case fromPaymentPrivateKey privKey body of
500+
newWits = case fromShelleyWitnessSigningKey body of
501501
C.Api.ShelleyKeyWitness _ wit -> Set.singleton wit
502502
_ -> Set.empty
503503

504-
fromPaymentPrivateKey xprv txBody =
504+
fromShelleyWitnessSigningKey txBody =
505505
C.Api.makeShelleyKeyWitness
506506
C.shelleyBasedEra
507507
(C.Api.ShelleyTxBody C.Api.ShelleyBasedEraBabbage txBody notUsed notUsed notUsed notUsed)
508-
(C.Api.WitnessPaymentExtendedKey (C.Api.PaymentExtendedSigningKey xprv))
508+
witness
509509
where
510510
notUsed = undefined -- hack so we can reuse code from cardano-api
511511

0 commit comments

Comments
 (0)