Skip to content

Commit

Permalink
Add API estimateTransactionKeyWitnessCount
Browse files Browse the repository at this point in the history
Give an approximate count of the number of key witnesses
(i.e. signatures) a transaction will need.
  • Loading branch information
dcoutts committed Jul 8, 2021
1 parent a8e2460 commit ead1a15
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
1 change: 1 addition & 0 deletions cardano-api/src/Cardano/Api.hs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ module Cardano.Api (
transactionFee,
estimateTransactionFee,
evaluateTransactionFee,
estimateTransactionKeyWitnessCount,
evaluateTransactionBalance,

-- * Transaction metadata
Expand Down
55 changes: 55 additions & 0 deletions cardano-api/src/Cardano/Api/Fees.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
Expand All @@ -17,6 +18,7 @@ module Cardano.Api.Fees (
transactionFee,
estimateTransactionFee,
evaluateTransactionFee,
estimateTransactionKeyWitnessCount,

-- * Transaction balance
evaluateTransactionBalance,
Expand All @@ -27,6 +29,7 @@ import Prelude
import qualified Data.ByteString as BS
import Data.Set (Set)
import qualified Data.Set as Set
import qualified Data.Map as Map
import GHC.Records (HasField (..))
import Numeric.Natural
import Data.Sequence.Strict (StrictSeq(..))
Expand Down Expand Up @@ -207,6 +210,58 @@ evaluateTransactionFee pparams txbody keywitcount _byronwitcount =
withLedgerConstraints ShelleyBasedEraMary f = f
withLedgerConstraints ShelleyBasedEraAlonzo f = f

-- | Give an approximate count of the number of key witnesses (i.e. signatures)
-- a transaction will need.
--
-- This is an estimate not a precise count in that it can over-estimate: it
-- makes conservative assumptions such as all inputs are from distinct
-- addresses, but in principle multiple inputs can use the same address and we
-- only need a witness per address.
--
-- Similarly there can be overlap between the regular and collateral inputs,
-- but we conservatively assume they are distinct.
--
-- TODO: it is worth us considering a more precise count that relies on the
-- UTxO to resolve which inputs are for distinct addresses, and also to count
-- the number of Shelley vs Byron style witnesses.
--
estimateTransactionKeyWitnessCount :: TxBodyContent BuildTx era -> Word
estimateTransactionKeyWitnessCount TxBodyContent {
txIns,
txInsCollateral,
txExtraKeyWits,
txWithdrawals,
txCertificates,
txUpdateProposal
} =
fromIntegral $
length [ () | (_txin, BuildTxWith KeyWitness{}) <- txIns ]

+ case txInsCollateral of
TxInsCollateral _ txins
-> length txins
_ -> 0

+ case txExtraKeyWits of
TxExtraKeyWitnesses _ khs
-> length khs
_ -> 0

+ case txWithdrawals of
TxWithdrawals _ withdrawals
-> length [ () | (_, _, BuildTxWith KeyWitness{}) <- withdrawals ]
_ -> 0

+ case txCertificates of
TxCertificates _ _ (BuildTxWith witnesses)
-> length [ () | KeyWitness{} <- Map.elems witnesses ]
_ -> 0

+ case txUpdateProposal of
TxUpdateProposal _ (UpdateProposal updatePerGenesisKey _)
-> Map.size updatePerGenesisKey
_ -> 0


-- ----------------------------------------------------------------------------
-- Transaction balance
Expand Down

0 comments on commit ead1a15

Please sign in to comment.