Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Jörmungandr NetworkLayer postTx #463

Merged
merged 2 commits into from
Jun 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/jormungandr/src/Cardano/Wallet/Jormungandr/Api.hs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ instance MimeUnrender JormungandrBinary (Block Tx) where
mimeUnrender _ = pure . coerceBlock . runGet getBlock

instance MimeRender JormungandrBinary (Tx, [TxWitness]) where
mimeRender _ a = runPut $ putSignedTx a
mimeRender _ = runPut . putSignedTx

data Hex

Expand Down
5 changes: 5 additions & 0 deletions lib/jormungandr/src/Cardano/Wallet/Jormungandr/Network.hs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ mkJormungandrLayer mgr baseUrl = JormungandrLayer
(BlockId parentId)
(Just count)
left ErrGetDescendantsNetworkUnreachable <$> defaultHandler ctx x

-- Never returns 'Left ErrPostTxProtocolFailure'. Will currently return
-- 'Right ()' when submitting correctly formatted, but invalid transactions.
--
-- https://github.com/input-output-hk/jormungandr/blob/fe638a36d4be64e0c4b360ba1c041e8fa10ea024/jormungandr/src/rest/v0/message/post.rs#L25-L39
, postMessage = \tx -> void $ ExceptT $ do
run (cPostMessage tx) >>= \case
Left (FailureResponse e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,28 @@ import Cardano.Wallet.Jormungandr.Compatibility
( Jormungandr, Network (..), block0 )
import Cardano.Wallet.Jormungandr.Network
( BaseUrl (..), ErrUnexpectedNetworkFailure (..), Scheme (..) )
import Cardano.Wallet.Jormungandr.Primitive.Types
( Tx (..) )
import Cardano.Wallet.Network
( ErrGetBlock (..)
, ErrNetworkTip (..)
, ErrPostTx (..)
, NetworkLayer (..)
, defaultRetryPolicy
, waitForConnection
)
import Cardano.Wallet.Primitive.Types
( BlockHeader (..), Hash (..), SlotId (..) )
( Address (..)
, BlockHeader (..)
, Coin (..)
, Hash (..)
, SlotId (..)
, TxIn (..)
, TxOut (..)
, TxWitness (..)
)
import Cardano.Wallet.Unsafe
( unsafeRunExceptT )
( unsafeDecodeAddress, unsafeFromHex, unsafeRunExceptT )
import Control.Concurrent
( threadDelay )
import Control.Concurrent.Async
Expand Down Expand Up @@ -59,6 +70,7 @@ import Test.Hspec
, beforeAll
, describe
, it
, pendingWith
, shouldBe
, shouldReturn
, shouldSatisfy
Expand Down Expand Up @@ -149,6 +161,52 @@ spec = do
shouldThrow io $ \(ErrUnexpectedNetworkFailure link _) ->
show link == show (safeLink api (Proxy @GetTipId))
bracket (startNode wrongUrl wait) killNode test


-- NOTE: 'Right ()' just means that the format wasn't obviously wrong.
-- The tx may still be rejected.
describe "Submitting signed transactions (that are not obviously wrong)"
$ beforeAll startNode' $ afterAll killNode $ do

it "empty tx succeeds" $ \(_, nw) -> do
let signedEmpty = (Tx [] [], [])
runExceptT (postTx nw signedEmpty) `shouldReturn` Right ()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting 🤔


it "some tx succeeds" $ \(_, nw) -> do
let signed = (txNonEmpty, [pkWitness])
runExceptT (postTx nw signed) `shouldReturn` Right ()

it "more inputs than witnesses" $ \(_, nw) -> do
let signed = (txNonEmpty, [])
let err = Left $ ErrPostTxBadRequest ""
runExceptT (postTx nw signed) `shouldReturn` err

it "more witnesses than inputs - fine apparently" $ \(_, nw) -> do
-- Becase of how signed txs are encoded:
-- n :: Word8
-- m :: Word8
-- in_0 .. in_n :: [TxIn]
-- out_0 .. out_m :: [TxOut]
-- witness_0 .. witness_n :: [TxWitness]
--
-- this should in practice be like appending bytes to the end of
-- the message.
let signed = (txNonEmpty, [pkWitness, pkWitness, pkWitness])
runExceptT (postTx nw signed) `shouldReturn` Right ()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting as well. Maybe worth reporting to Jörmungandr?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


it "no input, one output" $ \(_, nw) -> do
let tx = (Tx []
[ (TxOut $ unsafeDecodeAddress proxy "ca1qwunuat6snw60g99ul6qvte98fjale2k0uu5mrymylqz2ntgzs6vs386wxd")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Coin 1227362560)
], [])
runExceptT (postTx nw tx) `shouldReturn` Right ()

it "fails when addresses and hashes have wrong length" $ \(_, nw) -> do
pendingWith "We need to handle errors in Jormungandr.Binary"
let tx = (Tx [] [ TxOut (Address "<not an address>") (Coin 1227362560) ], [])
let err = Left $ ErrPostTxBadRequest ""
runExceptT (postTx nw tx) `shouldReturn` err

where
url :: BaseUrl
url = BaseUrl Http "localhost" 8081 "/api"
Expand Down Expand Up @@ -178,3 +236,28 @@ spec = do
killNode (h, _) = do
cancel h
threadDelay (1 * second)
pkWitness :: TxWitness
pkWitness = TxWitness $ BS.pack $ replicate 64 3

proxy :: Proxy (Jormungandr 'Mainnet)
proxy = Proxy

txNonEmpty :: Tx
txNonEmpty = Tx
{ inputs =
[ (TxIn
{ inputId = Hash $ unsafeFromHex "666984dec4bc0ff1888be97bfe0694a96b35c58d025405ead51d5cc72a3019f4"
, inputIx = 0
}, Coin 934864225351)
]
, outputs =
[ TxOut
{ address = unsafeDecodeAddress proxy "ca1q0u7k6ltp3e52pch47rhdkld2gdvgu26rwyqh02csu3ah3384f2nvhlk7a6"
, coin = Coin 933636862791
}
, TxOut
{ address = unsafeDecodeAddress proxy "ca1qwunuat6snw60g99ul6qvte98fjale2k0uu5mrymylqz2ntgzs6vs386wxd"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Careful about line-length here 🙏

, coin = Coin 1227362560
}
]
}