module Data.Bitcoin.PaymentChannel.Internal.Bitcoin.LockTime where
import Data.Word (Word32)
import qualified Data.Serialize as Bin
import Data.Serialize.Put (putWord32le)
import Data.Serialize.Get (getWord32le)
import Data.Time.Clock
import Data.Time.Clock.POSIX
import Data.Typeable
import Data.Time.Format ()
data BitcoinLockTime =
LockTimeBlockHeight Word32 |
LockTimeDate UTCTime deriving (Eq, Ord, Typeable)
instance Show BitcoinLockTime where
show (LockTimeBlockHeight blockNum) = "block number " ++ show blockNum
show (LockTimeDate date) = show date
instance Bin.Serialize BitcoinLockTime where
put = putWord32le . toWord32
get = parseBitcoinLocktime <$> getWord32le
parseBitcoinLocktime :: Word32 -> BitcoinLockTime
parseBitcoinLocktime i
| i < 500000000 = LockTimeBlockHeight i
| i >= 500000000 = LockTimeDate $ posixSecondsToUTCTime (fromIntegral i)
| otherwise = error "GHC bug?"
toWord32 :: BitcoinLockTime -> Word32
toWord32 (LockTimeBlockHeight i) = i
toWord32 (LockTimeDate date) =
fromIntegral . round . utcTimeToPOSIXSeconds $ date
fromDate :: UTCTime -> BitcoinLockTime
fromDate = LockTimeDate
usesBlockHeight :: BitcoinLockTime -> Bool
usesBlockHeight (LockTimeBlockHeight _) = True
usesBlockHeight _ = False