script

A Script library.
git clone git://git.ppad.tech/script.git
Log | Files | Refs | LICENSE

commit 155e2b2e2833afc9892ebe72d66812d6b0b0cafd
parent f012f1dbfe06cc5db9ce142df1c7f240db5f2400
Author: Jared Tobin <jared@jtobin.io>
Date:   Sat, 18 Jan 2025 08:45:37 +0400

test: quickcheck skeleton

Diffstat:
Mlib/Bitcoin/Prim/Script.hs | 4++++
Mppad-btcprim.cabal | 4+++-
Mtest/Main.hs | 76+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
3 files changed, 72 insertions(+), 12 deletions(-)

diff --git a/lib/Bitcoin/Prim/Script.hs b/lib/Bitcoin/Prim/Script.hs @@ -37,6 +37,8 @@ fi :: (Num a, Integral b) => b -> a fi = fromIntegral {-# INLINE fi #-} +-- XX slow? + -- convert a pinned ByteArray to a ByteString ba_to_bs :: BA.ByteArray -> BS.ByteString ba_to_bs ba = unsafeDupablePerformIO $ do @@ -401,6 +403,8 @@ to_script = Script . BA.byteArrayFromList . fmap term_to_byte where BYTE w8 -> w8 {-# INLINE term_to_byte #-} +-- XX seems slow + -- | Unpack a 'Script' into a list of Script terms. from_script :: Script -> [Term] from_script (Script bs) = go 0 where diff --git a/ppad-btcprim.cabal b/ppad-btcprim.cabal @@ -27,13 +27,13 @@ library build-depends: base >= 4.9 && < 5 , bytestring >= 0.9 && < 0.13 - , primitive >= 0.8 && < 0.10 , ppad-base16 >= 0.1 && < 0.2 , ppad-base58 >= 0.1 && < 0.2 , ppad-bech32 >= 0.2 && < 0.3 , ppad-ripemd160 >= 0.1 && < 0.2 , ppad-secp256k1 >= 0.2.1 && < 0.3 , ppad-sha256 >= 0.2 && < 0.3 + , primitive >= 0.8 && < 0.10 test-suite btcprim-tests type: exitcode-stdio-1.0 @@ -53,6 +53,8 @@ test-suite btcprim-tests , ppad-ripemd160 , ppad-secp256k1 , ppad-sha256 + , primitive , tasty , tasty-hunit + , tasty-quickcheck diff --git a/test/Main.hs b/test/Main.hs @@ -1,27 +1,81 @@ +{-# OPTIONS_GHC -fno-warn-orphans #-} +{-# OPTIONS_GHC -fno-warn-unused-imports #-} +{-# LANGUAGE NumericUnderscores #-} {-# LANGUAGE OverloadedStrings #-} module Main where -import qualified Crypto.Curve.Secp256k1 as Secp256k1 +import Bitcoin.Prim.Script import qualified Crypto.Hash.SHA256 as SHA256 import qualified Crypto.Hash.RIPEMD160 as RIPEMD160 import qualified Data.ByteString as BS -import qualified Data.ByteString.Base58Check as B58 -import Bitcoin.Prim.Script +import qualified Data.Primitive.ByteArray as BA +import Data.Word (Word8) import Test.Tasty -import Test.Tasty.HUnit +import qualified Test.Tasty.HUnit as H +import qualified Test.Tasty.QuickCheck as Q + +-- types ---------------------------------------------------------------------- + +newtype BS = BS BS.ByteString + deriving (Eq, Show) + +bytes_list :: Int -> Q.Gen [Word8] +bytes_list k = do + l <- Q.chooseInt (0, k) + Q.vectorOf l Q.arbitrary + +bytes :: Int -> Q.Gen BS.ByteString +bytes k = do + l <- Q.chooseInt (0, k) + v <- Q.vectorOf l Q.arbitrary + pure (BS.pack v) + +instance Q.Arbitrary BS where + arbitrary = do + b <- bytes 10_000 + pure (BS b) + +instance Q.Arbitrary BA.ByteArray where + arbitrary = do + b <- bytes_list 10_000 + pure (BA.byteArrayFromList b) + +instance Q.Arbitrary Script where + arbitrary = fmap Script Q.arbitrary + +-- properties ----------------------------------------------------------------- + +from_base16_inverts_to_base16 :: Script -> Bool +from_base16_inverts_to_base16 s = + let mscript = from_base16 (to_base16 s) + in case mscript of + Nothing -> False + Just script -> script == s + +to_script_inverts_from_script :: Script -> Bool +to_script_inverts_from_script s = + let script = to_script (from_script s) + in script == s + +-- main ----------------------------------------------------------------------- main :: IO () -main = pure () +main = defaultMain $ + testGroup "ppad-base16" [ + testGroup "property tests" [ + Q.testProperty "from_base16 . to_base16 ~ id" $ + Q.withMaxSuccess 100 from_base16_inverts_to_base16 + -- , Q.testProperty "to_script . from_script ~ id" $ + -- Q.withMaxSuccess 100 to_script_inverts_from_script + ] + ] + + + -sec :: Integer -sec = 0x05 -pub :: Secp256k1.Pub -pub = Secp256k1.derive_pub sec -p2pkh = B58.encode 0x00 - (RIPEMD160.hash (SHA256.hash (Secp256k1.serialize_point pub))) -- p2pkh