{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}

module Cardano.CLI.Byron.Tx
  ( ByronTxError(..)
  , TxFile(..)
  , NewTxFile(..)
  , prettyAddress
  , readByronTx
  , normalByronTxToGenTx
  , txSpendGenesisUTxOByronPBFT
  , txSpendUTxOByronPBFT
  , nodeSubmitTx
  , renderByronTxError

    --TODO: remove when they are exported from the ledger
  , fromCborTxAux
  , toCborTxAux
  )
where

import           Cardano.Prelude hiding (option, trace, (%))
import           Prelude (error)

import           Control.Monad.Trans.Except.Extra (firstExceptT, left)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as LB
import qualified Data.Map.Strict as Map
import qualified Data.Text as T
import qualified Data.Vector as Vector
import           Formatting (sformat, (%))

import qualified Cardano.Binary as Binary

import           Cardano.Chain.Common (Address)
import qualified Cardano.Chain.Common as Common
import           Cardano.Chain.Genesis as Genesis
import           Cardano.Chain.Slotting (EpochSlots (..))
import           Cardano.Chain.UTxO (Tx (..), TxId, TxIn, TxOut, annotateTxAux, mkTxAux)
import qualified Cardano.Chain.UTxO as UTxO
import           Cardano.Crypto (ProtocolMagicId, SigningKey (..))
import qualified Cardano.Crypto.Hashing as Crypto
import qualified Cardano.Crypto.Signing as Crypto

import           Ouroboros.Consensus.Byron.Ledger (ByronBlock, GenTx (..))
import qualified Ouroboros.Consensus.Byron.Ledger as Byron
import           Ouroboros.Consensus.HardFork.Combinator.Degenerate (GenTx (DegenGenTx))

import           Cardano.Api.Typed (LocalNodeConnectInfo (..), NetworkId, NodeConsensusMode (..),
                     submitTxToNodeLocal, toByronProtocolMagicId)
import           Cardano.CLI.Environment
import           Cardano.CLI.Helpers (textShow)
import           Cardano.CLI.Types (SocketPath (..))

data ByronTxError
  = TxDeserialisationFailed !FilePath !Binary.DecoderError
  | EnvSocketError !EnvSocketError
  deriving Int -> ByronTxError -> ShowS
[ByronTxError] -> ShowS
ByronTxError -> String
(Int -> ByronTxError -> ShowS)
-> (ByronTxError -> String)
-> ([ByronTxError] -> ShowS)
-> Show ByronTxError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ByronTxError] -> ShowS
$cshowList :: [ByronTxError] -> ShowS
show :: ByronTxError -> String
$cshow :: ByronTxError -> String
showsPrec :: Int -> ByronTxError -> ShowS
$cshowsPrec :: Int -> ByronTxError -> ShowS
Show

renderByronTxError :: ByronTxError -> Text
renderByronTxError :: ByronTxError -> Text
renderByronTxError ByronTxError
err =
  case ByronTxError
err of
    TxDeserialisationFailed String
txFp DecoderError
decErr ->
      Text
"Transaction deserialisation failed at " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a. Show a => a -> Text
textShow String
txFp Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" Error: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> DecoderError -> Text
forall a. Show a => a -> Text
textShow DecoderError
decErr
    EnvSocketError EnvSocketError
envSockErr -> EnvSocketError -> Text
renderEnvSocketError EnvSocketError
envSockErr


newtype TxFile =
  TxFile FilePath
  deriving (TxFile -> TxFile -> Bool
(TxFile -> TxFile -> Bool)
-> (TxFile -> TxFile -> Bool) -> Eq TxFile
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TxFile -> TxFile -> Bool
$c/= :: TxFile -> TxFile -> Bool
== :: TxFile -> TxFile -> Bool
$c== :: TxFile -> TxFile -> Bool
Eq, Eq TxFile
Eq TxFile
-> (TxFile -> TxFile -> Ordering)
-> (TxFile -> TxFile -> Bool)
-> (TxFile -> TxFile -> Bool)
-> (TxFile -> TxFile -> Bool)
-> (TxFile -> TxFile -> Bool)
-> (TxFile -> TxFile -> TxFile)
-> (TxFile -> TxFile -> TxFile)
-> Ord TxFile
TxFile -> TxFile -> Bool
TxFile -> TxFile -> Ordering
TxFile -> TxFile -> TxFile
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TxFile -> TxFile -> TxFile
$cmin :: TxFile -> TxFile -> TxFile
max :: TxFile -> TxFile -> TxFile
$cmax :: TxFile -> TxFile -> TxFile
>= :: TxFile -> TxFile -> Bool
$c>= :: TxFile -> TxFile -> Bool
> :: TxFile -> TxFile -> Bool
$c> :: TxFile -> TxFile -> Bool
<= :: TxFile -> TxFile -> Bool
$c<= :: TxFile -> TxFile -> Bool
< :: TxFile -> TxFile -> Bool
$c< :: TxFile -> TxFile -> Bool
compare :: TxFile -> TxFile -> Ordering
$ccompare :: TxFile -> TxFile -> Ordering
$cp1Ord :: Eq TxFile
Ord, Int -> TxFile -> ShowS
[TxFile] -> ShowS
TxFile -> String
(Int -> TxFile -> ShowS)
-> (TxFile -> String) -> ([TxFile] -> ShowS) -> Show TxFile
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TxFile] -> ShowS
$cshowList :: [TxFile] -> ShowS
show :: TxFile -> String
$cshow :: TxFile -> String
showsPrec :: Int -> TxFile -> ShowS
$cshowsPrec :: Int -> TxFile -> ShowS
Show, String -> TxFile
(String -> TxFile) -> IsString TxFile
forall a. (String -> a) -> IsString a
fromString :: String -> TxFile
$cfromString :: String -> TxFile
IsString)

newtype NewTxFile =
  NewTxFile FilePath
  deriving (NewTxFile -> NewTxFile -> Bool
(NewTxFile -> NewTxFile -> Bool)
-> (NewTxFile -> NewTxFile -> Bool) -> Eq NewTxFile
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NewTxFile -> NewTxFile -> Bool
$c/= :: NewTxFile -> NewTxFile -> Bool
== :: NewTxFile -> NewTxFile -> Bool
$c== :: NewTxFile -> NewTxFile -> Bool
Eq, Eq NewTxFile
Eq NewTxFile
-> (NewTxFile -> NewTxFile -> Ordering)
-> (NewTxFile -> NewTxFile -> Bool)
-> (NewTxFile -> NewTxFile -> Bool)
-> (NewTxFile -> NewTxFile -> Bool)
-> (NewTxFile -> NewTxFile -> Bool)
-> (NewTxFile -> NewTxFile -> NewTxFile)
-> (NewTxFile -> NewTxFile -> NewTxFile)
-> Ord NewTxFile
NewTxFile -> NewTxFile -> Bool
NewTxFile -> NewTxFile -> Ordering
NewTxFile -> NewTxFile -> NewTxFile
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NewTxFile -> NewTxFile -> NewTxFile
$cmin :: NewTxFile -> NewTxFile -> NewTxFile
max :: NewTxFile -> NewTxFile -> NewTxFile
$cmax :: NewTxFile -> NewTxFile -> NewTxFile
>= :: NewTxFile -> NewTxFile -> Bool
$c>= :: NewTxFile -> NewTxFile -> Bool
> :: NewTxFile -> NewTxFile -> Bool
$c> :: NewTxFile -> NewTxFile -> Bool
<= :: NewTxFile -> NewTxFile -> Bool
$c<= :: NewTxFile -> NewTxFile -> Bool
< :: NewTxFile -> NewTxFile -> Bool
$c< :: NewTxFile -> NewTxFile -> Bool
compare :: NewTxFile -> NewTxFile -> Ordering
$ccompare :: NewTxFile -> NewTxFile -> Ordering
$cp1Ord :: Eq NewTxFile
Ord, Int -> NewTxFile -> ShowS
[NewTxFile] -> ShowS
NewTxFile -> String
(Int -> NewTxFile -> ShowS)
-> (NewTxFile -> String)
-> ([NewTxFile] -> ShowS)
-> Show NewTxFile
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NewTxFile] -> ShowS
$cshowList :: [NewTxFile] -> ShowS
show :: NewTxFile -> String
$cshow :: NewTxFile -> String
showsPrec :: Int -> NewTxFile -> ShowS
$cshowsPrec :: Int -> NewTxFile -> ShowS
Show, String -> NewTxFile
(String -> NewTxFile) -> IsString NewTxFile
forall a. (String -> a) -> IsString a
fromString :: String -> NewTxFile
$cfromString :: String -> NewTxFile
IsString)


-- | Pretty-print an address in its Base58 form, and also
--   its full structure.
prettyAddress :: Common.Address -> Text
prettyAddress :: Address -> Text
prettyAddress Address
addr = Format Text (Address -> Address -> Text)
-> Address -> Address -> Text
forall a. Format Text a -> a
sformat
  (Format (Address -> Text) (Address -> Address -> Text)
forall r. Format r (Address -> r)
Common.addressF Format (Address -> Text) (Address -> Address -> Text)
-> Format Text (Address -> Text)
-> Format Text (Address -> Address -> Text)
forall r a r'. Format r a -> Format r' r -> Format r' a
%Format (Address -> Text) (Address -> Text)
"\n"Format (Address -> Text) (Address -> Text)
-> Format Text (Address -> Text) -> Format Text (Address -> Text)
forall r a r'. Format r a -> Format r' r -> Format r' a
%Format Text (Address -> Text)
forall r. Format r (Address -> r)
Common.addressDetailedF)
  Address
addr Address
addr

readByronTx :: TxFile -> ExceptT ByronTxError IO (GenTx ByronBlock)
readByronTx :: TxFile -> ExceptT ByronTxError IO (GenTx ByronBlock)
readByronTx (TxFile String
fp) = do
  ByteString
txBS <- IO ByteString -> ExceptT ByronTxError IO ByteString
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> ExceptT ByronTxError IO ByteString)
-> IO ByteString -> ExceptT ByronTxError IO ByteString
forall a b. (a -> b) -> a -> b
$ String -> IO ByteString
LB.readFile String
fp
  case ByteString -> Either DecoderError (ATxAux ByteString)
fromCborTxAux ByteString
txBS of
    Left DecoderError
e -> ByronTxError -> ExceptT ByronTxError IO (GenTx ByronBlock)
forall (m :: * -> *) x a. Monad m => x -> ExceptT x m a
left (ByronTxError -> ExceptT ByronTxError IO (GenTx ByronBlock))
-> ByronTxError -> ExceptT ByronTxError IO (GenTx ByronBlock)
forall a b. (a -> b) -> a -> b
$ String -> DecoderError -> ByronTxError
TxDeserialisationFailed String
fp DecoderError
e
    Right ATxAux ByteString
tx -> GenTx ByronBlock -> ExceptT ByronTxError IO (GenTx ByronBlock)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ATxAux ByteString -> GenTx ByronBlock
normalByronTxToGenTx ATxAux ByteString
tx)

-- | The 'GenTx' is all the kinds of transactions that can be submitted
-- and \"normal\" Byron transactions are just one of the kinds.
normalByronTxToGenTx :: UTxO.ATxAux ByteString -> GenTx ByronBlock
normalByronTxToGenTx :: ATxAux ByteString -> GenTx ByronBlock
normalByronTxToGenTx ATxAux ByteString
tx' = TxId -> ATxAux ByteString -> GenTx ByronBlock
Byron.ByronTx (ATxAux ByteString -> TxId
Byron.byronIdTx ATxAux ByteString
tx') ATxAux ByteString
tx'

-- | Given a Tx id, produce a UTxO Tx input witness, by signing it
--   with respect to a given protocol magic.
signTxId :: ProtocolMagicId -> SigningKey -> TxId -> UTxO.TxInWitness
signTxId :: ProtocolMagicId -> SigningKey -> TxId -> TxInWitness
signTxId ProtocolMagicId
pmid SigningKey
sk TxId
txid =
  VerificationKey -> TxSig -> TxInWitness
UTxO.VKWitness
  (SigningKey -> VerificationKey
Crypto.toVerification SigningKey
sk)
  (ProtocolMagicId -> SignTag -> SigningKey -> TxSigData -> TxSig
forall a.
ToCBOR a =>
ProtocolMagicId -> SignTag -> SigningKey -> a -> Signature a
Crypto.sign
    ProtocolMagicId
pmid
    SignTag
Crypto.SignTx
    SigningKey
sk
    (TxId -> TxSigData
UTxO.TxSigData TxId
txid))

-- | Given a genesis, and a pair of a genesis public key and address,
--   reconstruct a TxIn corresponding to the genesis UTxO entry.
genesisUTxOTxIn :: Genesis.Config -> Crypto.VerificationKey -> Common.Address -> UTxO.TxIn
genesisUTxOTxIn :: Config -> VerificationKey -> Address -> TxIn
genesisUTxOTxIn Config
gc VerificationKey
vk Address
genAddr =
  Maybe TxIn -> TxIn
handleMissingAddr (Maybe TxIn -> TxIn) -> Maybe TxIn -> TxIn
forall a b. (a -> b) -> a -> b
$ (TxIn, TxOut) -> TxIn
forall a b. (a, b) -> a
fst ((TxIn, TxOut) -> TxIn) -> Maybe (TxIn, TxOut) -> Maybe TxIn
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Address -> Map Address (TxIn, TxOut) -> Maybe (TxIn, TxOut)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Address
genAddr Map Address (TxIn, TxOut)
initialUtxo
  where
    initialUtxo :: Map Common.Address (UTxO.TxIn, UTxO.TxOut)
    initialUtxo :: Map Address (TxIn, TxOut)
initialUtxo =
          [(Address, (TxIn, TxOut))] -> Map Address (TxIn, TxOut)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
        ([(Address, (TxIn, TxOut))] -> Map Address (TxIn, TxOut))
-> (Config -> [(Address, (TxIn, TxOut))])
-> Config
-> Map Address (TxIn, TxOut)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((TxIn, TxOut) -> Maybe (Address, (TxIn, TxOut)))
-> [(TxIn, TxOut)] -> [(Address, (TxIn, TxOut))]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\(TxIn
inp, TxOut
out) -> TxIn -> Address -> TxOut -> (Address, (TxIn, TxOut))
mkEntry TxIn
inp Address
genAddr (TxOut -> (Address, (TxIn, TxOut)))
-> Maybe TxOut -> Maybe (Address, (TxIn, TxOut))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VerificationKey -> TxOut -> Maybe TxOut
keyMatchesUTxO VerificationKey
vk TxOut
out)
        ([(TxIn, TxOut)] -> [(Address, (TxIn, TxOut))])
-> (Config -> [(TxIn, TxOut)])
-> Config
-> [(Address, (TxIn, TxOut))]
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [(CompactTxIn, CompactTxOut)] -> [(TxIn, TxOut)]
fromCompactTxInTxOutList
        ([(CompactTxIn, CompactTxOut)] -> [(TxIn, TxOut)])
-> (Config -> [(CompactTxIn, CompactTxOut)])
-> Config
-> [(TxIn, TxOut)]
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Map CompactTxIn CompactTxOut -> [(CompactTxIn, CompactTxOut)]
forall k a. Map k a -> [(k, a)]
Map.toList
        (Map CompactTxIn CompactTxOut -> [(CompactTxIn, CompactTxOut)])
-> (Config -> Map CompactTxIn CompactTxOut)
-> Config
-> [(CompactTxIn, CompactTxOut)]
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. UTxO -> Map CompactTxIn CompactTxOut
UTxO.unUTxO
        (UTxO -> Map CompactTxIn CompactTxOut)
-> (Config -> UTxO) -> Config -> Map CompactTxIn CompactTxOut
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Config -> UTxO
UTxO.genesisUtxo
        (Config -> Map Address (TxIn, TxOut))
-> Config -> Map Address (TxIn, TxOut)
forall a b. (a -> b) -> a -> b
$ Config
gc
      where
        mkEntry :: UTxO.TxIn
                -> Address
                -> UTxO.TxOut
                -> (Address, (UTxO.TxIn, UTxO.TxOut))
        mkEntry :: TxIn -> Address -> TxOut -> (Address, (TxIn, TxOut))
mkEntry TxIn
inp Address
addr TxOut
out = (Address
addr, (TxIn
inp, TxOut
out))

    fromCompactTxInTxOutList :: [(UTxO.CompactTxIn, UTxO.CompactTxOut)]
                             -> [(UTxO.TxIn, UTxO.TxOut)]
    fromCompactTxInTxOutList :: [(CompactTxIn, CompactTxOut)] -> [(TxIn, TxOut)]
fromCompactTxInTxOutList =
        ((CompactTxIn, CompactTxOut) -> (TxIn, TxOut))
-> [(CompactTxIn, CompactTxOut)] -> [(TxIn, TxOut)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ((CompactTxIn -> TxIn)
-> (CompactTxOut -> TxOut)
-> (CompactTxIn, CompactTxOut)
-> (TxIn, TxOut)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap CompactTxIn -> TxIn
UTxO.fromCompactTxIn CompactTxOut -> TxOut
UTxO.fromCompactTxOut)

    keyMatchesUTxO :: Crypto.VerificationKey -> UTxO.TxOut -> Maybe UTxO.TxOut
    keyMatchesUTxO :: VerificationKey -> TxOut -> Maybe TxOut
keyMatchesUTxO VerificationKey
key TxOut
out =
      if VerificationKey -> Address -> Bool
Common.checkVerKeyAddress VerificationKey
key (TxOut -> Address
UTxO.txOutAddress TxOut
out)
      then TxOut -> Maybe TxOut
forall a. a -> Maybe a
Just TxOut
out else Maybe TxOut
forall a. Maybe a
Nothing

    handleMissingAddr :: Maybe UTxO.TxIn -> UTxO.TxIn
    handleMissingAddr :: Maybe TxIn -> TxIn
handleMissingAddr  = TxIn -> Maybe TxIn -> TxIn
forall a. a -> Maybe a -> a
fromMaybe (TxIn -> Maybe TxIn -> TxIn)
-> (String -> TxIn) -> String -> Maybe TxIn -> TxIn
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. String -> TxIn
forall a. HasCallStack => String -> a
error
      (String -> Maybe TxIn -> TxIn) -> String -> Maybe TxIn -> TxIn
forall a b. (a -> b) -> a -> b
$  String
"\nGenesis UTxO has no address\n"
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack (Address -> Text
prettyAddress Address
genAddr)
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"\n\nIt has the following, though:\n\n"
      String -> ShowS
forall a. Semigroup a => a -> a -> a
<> [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
Cardano.Prelude.concat (Text -> String
T.unpack (Text -> String) -> (Address -> Text) -> Address -> String
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Address -> Text
prettyAddress (Address -> String) -> [Address] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Address (TxIn, TxOut) -> [Address]
forall k a. Map k a -> [k]
Map.keys Map Address (TxIn, TxOut)
initialUtxo)

-- | Generate a transaction spending genesis UTxO at a given address,
--   to given outputs, signed by the given key.
txSpendGenesisUTxOByronPBFT
  :: Genesis.Config
  -> NetworkId
  -> SigningKey
  -> Address
  -> NonEmpty TxOut
  -> UTxO.ATxAux ByteString
txSpendGenesisUTxOByronPBFT :: Config
-> NetworkId
-> SigningKey
-> Address
-> NonEmpty TxOut
-> ATxAux ByteString
txSpendGenesisUTxOByronPBFT Config
gc NetworkId
nw SigningKey
sk Address
genAddr NonEmpty TxOut
outs =
    TxAux -> ATxAux ByteString
annotateTxAux (TxAux -> ATxAux ByteString) -> TxAux -> ATxAux ByteString
forall a b. (a -> b) -> a -> b
$ Tx -> TxWitness -> TxAux
mkTxAux Tx
tx (TxInWitness -> TxWitness
forall (f :: * -> *) a. Applicative f => a -> f a
pure TxInWitness
wit)
  where
    tx :: Tx
tx = NonEmpty TxIn -> NonEmpty TxOut -> TxAttributes -> Tx
UnsafeTx (TxIn -> NonEmpty TxIn
forall (f :: * -> *) a. Applicative f => a -> f a
pure TxIn
txIn) NonEmpty TxOut
outs TxAttributes
txattrs

    wit :: TxInWitness
wit = ProtocolMagicId -> SigningKey -> TxId -> TxInWitness
signTxId (NetworkId -> ProtocolMagicId
toByronProtocolMagicId NetworkId
nw) SigningKey
sk (Tx -> TxId
forall a. ToCBOR a => a -> Hash a
Crypto.serializeCborHash Tx
tx)

    txIn :: UTxO.TxIn
    txIn :: TxIn
txIn  = Config -> VerificationKey -> Address -> TxIn
genesisUTxOTxIn Config
gc (SigningKey -> VerificationKey
Crypto.toVerification SigningKey
sk) Address
genAddr

    txattrs :: TxAttributes
txattrs = () -> TxAttributes
forall h. h -> Attributes h
Common.mkAttributes ()

-- | Generate a transaction from given Tx inputs to outputs,
--   signed by the given key.
txSpendUTxOByronPBFT
  :: NetworkId
  -> SigningKey
  -> NonEmpty TxIn
  -> NonEmpty TxOut
  -> UTxO.ATxAux ByteString
txSpendUTxOByronPBFT :: NetworkId
-> SigningKey
-> NonEmpty TxIn
-> NonEmpty TxOut
-> ATxAux ByteString
txSpendUTxOByronPBFT NetworkId
nw SigningKey
sk NonEmpty TxIn
ins NonEmpty TxOut
outs =
    TxAux -> ATxAux ByteString
annotateTxAux (TxAux -> ATxAux ByteString) -> TxAux -> ATxAux ByteString
forall a b. (a -> b) -> a -> b
$ Tx -> TxWitness -> TxAux
mkTxAux Tx
tx (TxInWitness -> TxWitness
forall a. a -> Vector a
Vector.singleton TxInWitness
wit)
  where
    tx :: Tx
tx = NonEmpty TxIn -> NonEmpty TxOut -> TxAttributes -> Tx
UnsafeTx NonEmpty TxIn
ins NonEmpty TxOut
outs TxAttributes
txattrs

    wit :: TxInWitness
wit = ProtocolMagicId -> SigningKey -> TxId -> TxInWitness
signTxId (NetworkId -> ProtocolMagicId
toByronProtocolMagicId NetworkId
nw) SigningKey
sk (Tx -> TxId
forall a. ToCBOR a => a -> Hash a
Crypto.serializeCborHash Tx
tx)

    txattrs :: TxAttributes
txattrs = () -> TxAttributes
forall h. h -> Attributes h
Common.mkAttributes ()


-- | Submit a transaction to a node specified by topology info.
nodeSubmitTx
  :: NetworkId
  -> GenTx ByronBlock
  -> ExceptT ByronTxError IO ()
nodeSubmitTx :: NetworkId -> GenTx ByronBlock -> ExceptT ByronTxError IO ()
nodeSubmitTx NetworkId
network GenTx ByronBlock
gentx = do
    SocketPath String
socketPath <- (EnvSocketError -> ByronTxError)
-> ExceptT EnvSocketError IO SocketPath
-> ExceptT ByronTxError IO SocketPath
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT EnvSocketError -> ByronTxError
EnvSocketError ExceptT EnvSocketError IO SocketPath
readEnvSocketPath
    let connctInfo :: LocalNodeConnectInfo ByronMode (HardForkBlock '[ByronBlock])
connctInfo =
          LocalNodeConnectInfo :: forall mode block.
String
-> NetworkId
-> NodeConsensusMode mode block
-> LocalNodeConnectInfo mode block
LocalNodeConnectInfo {
            localNodeSocketPath :: String
localNodeSocketPath    = String
socketPath,
            localNodeNetworkId :: NetworkId
localNodeNetworkId     = NetworkId
network,
            localNodeConsensusMode :: NodeConsensusMode ByronMode (HardForkBlock '[ByronBlock])
localNodeConsensusMode = EpochSlots
-> NodeConsensusMode ByronMode (HardForkBlock '[ByronBlock])
ByronMode (Word64 -> EpochSlots
EpochSlots Word64
21600)
          }
    SubmitResult (HardForkApplyTxErr '[ByronBlock])
_res <- IO (SubmitResult (HardForkApplyTxErr '[ByronBlock]))
-> ExceptT
     ByronTxError IO (SubmitResult (HardForkApplyTxErr '[ByronBlock]))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (SubmitResult (HardForkApplyTxErr '[ByronBlock]))
 -> ExceptT
      ByronTxError IO (SubmitResult (HardForkApplyTxErr '[ByronBlock])))
-> IO (SubmitResult (HardForkApplyTxErr '[ByronBlock]))
-> ExceptT
     ByronTxError IO (SubmitResult (HardForkApplyTxErr '[ByronBlock]))
forall a b. (a -> b) -> a -> b
$ LocalNodeConnectInfo ByronMode (HardForkBlock '[ByronBlock])
-> GenTx (HardForkBlock '[ByronBlock])
-> IO (SubmitResult (ApplyTxErr (HardForkBlock '[ByronBlock])))
forall mode block.
(ShowProxy block, ShowProxy (ApplyTxErr block),
 ShowProxy (Query block), ShowProxy (GenTx block),
 ShowQuery (Query block)) =>
LocalNodeConnectInfo mode block
-> GenTx block -> IO (SubmitResult (ApplyTxErr block))
submitTxToNodeLocal LocalNodeConnectInfo ByronMode (HardForkBlock '[ByronBlock])
connctInfo (GenTx ByronBlock -> GenTx (HardForkBlock '[ByronBlock])
forall b. NoHardForks b => GenTx b -> GenTx (HardForkBlock '[b])
DegenGenTx GenTx ByronBlock
gentx)
    --TODO: print failures
    () -> ExceptT ByronTxError IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()


--TODO: remove these local definitions when the updated ledger lib is available
fromCborTxAux :: LB.ByteString ->  Either Binary.DecoderError (UTxO.ATxAux B.ByteString)
fromCborTxAux :: ByteString -> Either DecoderError (ATxAux ByteString)
fromCborTxAux ByteString
lbs =
    (ATxAux ByteSpan -> ATxAux ByteString)
-> Either DecoderError (ATxAux ByteSpan)
-> Either DecoderError (ATxAux ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ByteString -> ATxAux ByteSpan -> ATxAux ByteString
forall (f :: * -> *).
Functor f =>
ByteString -> f ByteSpan -> f ByteString
annotationBytes ByteString
lbs)
      (Either DecoderError (ATxAux ByteSpan)
 -> Either DecoderError (ATxAux ByteString))
-> Either DecoderError (ATxAux ByteSpan)
-> Either DecoderError (ATxAux ByteString)
forall a b. (a -> b) -> a -> b
$ Text
-> (forall s. Decoder s (ATxAux ByteSpan))
-> ByteString
-> Either DecoderError (ATxAux ByteSpan)
forall a.
Text
-> (forall s. Decoder s a) -> ByteString -> Either DecoderError a
Binary.decodeFullDecoder Text
"Cardano.Chain.UTxO.TxAux.fromCborTxAux"
                                 forall s. Decoder s (ATxAux ByteSpan)
forall a s. FromCBOR a => Decoder s a
Binary.fromCBOR ByteString
lbs
  where
    annotationBytes :: Functor f => LB.ByteString -> f Binary.ByteSpan -> f B.ByteString
    annotationBytes :: ByteString -> f ByteSpan -> f ByteString
annotationBytes ByteString
bytes = (ByteSpan -> ByteString) -> f ByteSpan -> f ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ByteString -> ByteString
LB.toStrict (ByteString -> ByteString)
-> (ByteSpan -> ByteString) -> ByteSpan -> ByteString
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ByteString -> ByteSpan -> ByteString
Binary.slice ByteString
bytes)

toCborTxAux :: UTxO.ATxAux ByteString -> LB.ByteString
toCborTxAux :: ATxAux ByteString -> ByteString
toCborTxAux = ByteString -> ByteString
LB.fromStrict (ByteString -> ByteString)
-> (ATxAux ByteString -> ByteString)
-> ATxAux ByteString
-> ByteString
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ATxAux ByteString -> ByteString
forall a. ATxAux a -> a
UTxO.aTaAnnotation -- The ByteString anotation is the CBOR encoded version.