bitcoin-compact-filters 0.1.0.2 → 0.1.1
raw patch · 2 files changed
+51/−22 lines, 2 filesdep −bitstreamdep ~aesondep ~basedep ~haskoin-core
Dependencies removed: bitstream
Dependency ranges changed: aeson, base, haskoin-core, memory, text, transformers
Files
- bitcoin-compact-filters.cabal +11/−11
- src/Bitcoin/CompactFilter.hs +40/−11
bitcoin-compact-filters.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: bitcoin-compact-filters-version: 0.1.0.2+version: 0.1.1 synopsis: BIP 158 compact block filters copyright: 2020 Bitnomial, Inc.@@ -15,19 +15,20 @@ examples/*.json tested-with:- GHC == 8.10.4- , GHC == 8.10.5- , GHC == 9.0.1+ GHC == 8.10.7+ , GHC == 9.0.2+ , GHC == 9.2.7+ , GHC == 9.4.4 common core default-language: Haskell2010 ghc-options: -Wall build-depends:- base >=4.12 && <4.16+ base >=4.12 && <4.19 , bytestring >=0.10 && <0.12 , cereal ^>=0.5- , haskoin-core >=0.17.1 && <0.21- , text ^>=1.2+ , haskoin-core >=0.17.1 && <0.22+ , text >=1.2 && <2.1 library@@ -38,9 +39,8 @@ Bitcoin.CompactFilter build-depends:- bitstream ^>=0.3.0.1- , transformers ^>=0.5- , memory >=0.15 && <0.17+ transformers >=0.5 && <0.7+ , memory >=0.15 && <0.19 test-suite bitcoin-cf-tests@@ -61,7 +61,7 @@ Paths_bitcoin_compact_filters build-depends:- aeson >=1.0 && <1.6+ aeson >=1.0 && <2.2 , bitcoin-compact-filters , tasty >=1.0 && <1.5 , tasty-hunit >=0.9 && <0.11
src/Bitcoin/CompactFilter.hs view
@@ -19,9 +19,7 @@ import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.State.Strict (StateT, evalStateT) import qualified Control.Monad.Trans.State.Strict as St-import Data.Bits (shiftL, shiftR, testBit)-import Data.Bitstream (Bitstream, Right)-import qualified Data.Bitstream as BiS+import Data.Bits (clearBit, setBit, shiftL, shiftR, testBit) import Data.Bool (bool) import Data.ByteArray.Hash ( SipHash (..),@@ -30,6 +28,7 @@ ) import Data.ByteString (ByteString) import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BSL import Data.Foldable (foldl') import Data.List (sort) import Data.Serialize (@@ -72,8 +71,8 @@ -- | Hashes of scripts in the block newtype BlockFilter = BlockFilter- { -- | Get the list of hashes in increasing order- blockFilter :: [Word64]+ { blockFilter :: [Word64]+ -- ^ Get the list of hashes in increasing order } deriving (Eq, Show) @@ -221,6 +220,36 @@ | otherwise -> x0 : dedup xs xs -> xs +{- | Golomb coded sets are not naturally expressed in bytes, but rather as a bit+ stream+-}+data Bitstream+ = Bitstream+ BSL.ByteString+ -- ^ Complete bytes written so far, in reverse order+ {-# UNPACK #-} !Word8+ -- ^ The current work byte+ {-# UNPACK #-} !Int+ -- ^ Pointer to the first open bit++emptyB :: Bitstream+emptyB = Bitstream mempty 0 7++appendBit :: Bool -> Bitstream -> Bitstream+appendBit b (Bitstream bytes inFlight cursor)+ | cursor == 0 = Bitstream (BSL.cons nextInFlight bytes) 0 7+ | otherwise = Bitstream bytes nextInFlight (cursor - 1)+ where+ nextInFlight = bool clearBit setBit b inFlight cursor++asByteString :: Bitstream -> ByteString+asByteString (Bitstream bytes inFlight cursor) =+ BSL.toStrict $ BSL.reverse paddedBytes+ where+ paddedBytes+ | cursor == 7 = bytes+ | otherwise = BSL.cons inFlight bytes+ constructGCS :: -- | modulus Int ->@@ -228,8 +257,8 @@ [Word64] -> ByteString constructGCS p =- BiS.toByteString- . foldMap (golombRiceEncode p)+ asByteString+ . foldl' (golombRiceEncode p) emptyB . diffs diffs :: Num a => [a] -> [a]@@ -239,12 +268,12 @@ unDiffs (x : xs) = scanl (+) x xs unDiffs [] = [] -golombRiceEncode :: Int -> Word64 -> Bitstream Right-golombRiceEncode p v = x <> BiS.singleton False <> y+golombRiceEncode :: Int -> Bitstream -> Word64 -> Bitstream+golombRiceEncode p b v = foldl' (flip nextBit) prefix [p - i | i <- [1 .. p]] where q = fromIntegral $ v `shiftR` p- x = BiS.replicate q True- y = BiS.fromNBits p v+ prefix = appendBit False $ iterate (appendBit True) b !! q+ nextBit = appendBit . testBit v fromBits :: Num a => [Bool] -> a fromBits = foldl' onBit 0