Skip to content

Commit

Permalink
implement txId using CBOR encoders
Browse files Browse the repository at this point in the history
  • Loading branch information
KtorZ committed Mar 6, 2019
1 parent 3358405 commit 8c206ec
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 12 deletions.
2 changes: 2 additions & 0 deletions cardano-wallet.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ library
, bytestring
, cborg
, containers
, cryptonite
, deepseq
, digest
, memory
hs-source-dirs:
src
exposed-modules:
Expand Down
28 changes: 25 additions & 3 deletions src/Cardano/Wallet/Binary.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeApplications #-}

-- |
-- Copyright: © 2018-2019 IOHK
Expand All @@ -16,9 +17,11 @@ module Cardano.Wallet.Binary
-- * Decoding
decodeBlock
, decodeBlockHeader
, decodeTx

-- * Encoding
, encodeTx
, txId

-- * Helpers
, inspectNextToken
Expand All @@ -40,6 +43,10 @@ import Cardano.Wallet.Primitive
)
import Control.Monad
( void )
import Crypto.Hash
( hash )
import Crypto.Hash.Algorithms
( Blake2b_256 )
import Data.ByteString
( ByteString )
import Data.Digest.CRC32
Expand All @@ -55,6 +62,7 @@ import qualified Codec.CBOR.Decoding as CBOR
import qualified Codec.CBOR.Encoding as CBOR
import qualified Codec.CBOR.Read as CBOR
import qualified Codec.CBOR.Write as CBOR
import qualified Data.ByteArray as BA
import qualified Data.ByteString.Lazy as BL
import qualified Data.Set as Set

Expand Down Expand Up @@ -319,6 +327,16 @@ decodeSignature = do
2 -> decodeProxySignature decodeHeavyIndex
_ -> fail $ "decodeSignature: unknown signature constructor: " <> show t

decodeSignedTx :: CBOR.Decoder s Tx
decodeSignedTx = do
_ <- CBOR.decodeListLenCanonicalOf 2
_ <- CBOR.decodeListLenCanonicalOf 3
ins <- decodeListIndef decodeTxIn
outs <- decodeListIndef decodeTxOut
_ <- decodeAttributes
_ <- decodeList decodeTxWitness
return $ Tx ins outs

decodeSharesProof :: CBOR.Decoder s ()
decodeSharesProof = do
_ <- CBOR.decodeBytes -- Shares Hash
Expand All @@ -341,16 +359,14 @@ decodeSoftwareVersion = do

decodeTx :: CBOR.Decoder s Tx
decodeTx = do
_ <- CBOR.decodeListLenCanonicalOf 2
_ <- CBOR.decodeListLenCanonicalOf 3
ins <- decodeListIndef decodeTxIn
outs <- decodeListIndef decodeTxOut
_ <- decodeAttributes
_ <- decodeList decodeTxWitness
return $ Tx ins outs

decodeTxPayload :: CBOR.Decoder s (Set Tx)
decodeTxPayload = Set.fromList <$> decodeListIndef decodeTx
decodeTxPayload = Set.fromList <$> decodeListIndef decodeSignedTx

{-# ANN decodeTxIn ("HLint: ignore Use <$>" :: String) #-}
decodeTxIn :: CBOR.Decoder s TxIn
Expand Down Expand Up @@ -407,6 +423,12 @@ decodeUpdateProof = do

-- * Encoding

-- | Compute a transaction id; assumed to be effectively injective.
-- It returns an hex-encoded 64-byte hash.
txId :: Tx -> Hash "Tx"
txId =
Hash . BA.convert . hash @_ @Blake2b_256 . CBOR.toStrictByteString . encodeTx

encodeAddressPayload :: ByteString -> CBOR.Encoding
encodeAddressPayload payload = mempty
<> CBOR.encodeListLen 2
Expand Down
4 changes: 2 additions & 2 deletions src/Cardano/Wallet/Primitive.hs
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ instance NFData Tx


data TxIn = TxIn
{ txId
{ inputId
:: !(Hash "Tx")
, txIx
, inputIx
:: !Word32
} deriving (Show, Generic, Eq, Ord)

Expand Down
38 changes: 31 additions & 7 deletions test/unit/Cardano/Wallet/BinarySpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Cardano.Wallet.BinarySpec (spec) where
import Prelude

import Cardano.Wallet.Binary
( decodeBlock, decodeBlockHeader )
( decodeBlock, decodeBlockHeader, decodeTx, encodeTx, txId )
import Cardano.Wallet.Primitive
( Address (..)
, Block (..)
Expand All @@ -27,6 +27,7 @@ import Test.Hspec

import qualified Codec.CBOR.Decoding as CBOR
import qualified Codec.CBOR.Read as CBOR
import qualified Codec.CBOR.Write as CBOR
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Lazy.Char8 as L8
import qualified Data.Set as Set
Expand Down Expand Up @@ -55,6 +56,29 @@ spec = do
let decoded = unsafeDeserialiseFromBytes decodeBlock bs
decoded `shouldBe` block3

describe "Encoding Tx" $ do
let txs = Set.toList (transactions block2 <> transactions block3)
let roundTripTx tx = do
let bytes = CBOR.toLazyByteString (encodeTx tx)
let tx' = unsafeDeserialiseFromBytes decodeTx bytes
tx `shouldBe` tx'

it "encode . decode = pure (1)" $ do
roundTripTx (txs !! 0)

it "encode . decode = pure (2)" $ do
roundTripTx (txs !! 1)

it "should compute correct txId (1)" $ do
let hash = txId (txs !! 0)
let hash' = hash16 "c470563001e448e61ff1268c2a6eb458ace1d04011a02cb262b6d709d66c23d0"
hash `shouldBe` hash'

it "should compute correct txId (2)" $ do
let hash = txId (txs !! 1)
let hash' = hash16 "d30d37f1f8674c6c33052826fdc5bc198e3e95c150364fd775d4bc663ae6a9e6"
hash `shouldBe` hash'


-- A mainnet block header
blockHeader1 :: BlockHeader
Expand Down Expand Up @@ -87,8 +111,8 @@ block2 = Block
[ Tx
{ inputs =
[ TxIn
{ txId = hash16 "60dbb2679ee920540c18195a3d92ee9be50aee6ed5f891d92d51db8a76b02cd2"
, txIx = 3
{ inputId = hash16 "60dbb2679ee920540c18195a3d92ee9be50aee6ed5f891d92d51db8a76b02cd2"
, inputIx = 3
}
]
, outputs =
Expand Down Expand Up @@ -117,11 +141,11 @@ block3 = Block
[ Tx
{ inputs =
[ TxIn
{ txId = hash16 "6967e2b5c3ad5ae07a9bd8d888f1836195a04f7a1cb4b6d083261870068fab1b"
, txIx = 1}
{ inputId = hash16 "6967e2b5c3ad5ae07a9bd8d888f1836195a04f7a1cb4b6d083261870068fab1b"
, inputIx = 1}
, TxIn
{ txId = hash16 "7064addc0968bccd7d57d2e7aa1e9c2f666d8387042483fc1e87200cfb96c8f1"
, txIx = 0} ]
{ inputId = hash16 "7064addc0968bccd7d57d2e7aa1e9c2f666d8387042483fc1e87200cfb96c8f1"
, inputIx = 0} ]
, outputs =
[ TxOut
{ address = addr58 "37btjrVyb4KBsw2f3V76ntfwqDPgyf3QmmdsrTSmCnuTGYtS9JgVXzxeQEsKjgWurKoyw9BDNEtLxWtU9znK49SC8bLTirk6YqcAESFxXJkSyXhQKL"
Expand Down

0 comments on commit 8c206ec

Please sign in to comment.