module Network.Polkadot.Extrinsic.Era
( Era(..)
, new_mortal_compact
, birth
, death
) where
import Codec.Scale.Class (Decode (..), Encode (..))
import Codec.Scale.Core ()
import Data.Bits (shiftL, shiftR, (.|.))
import Data.Word (Word16, Word32, Word8, byteSwap16)
data Era
= ImmortalEra
| MortalEra !Word32 !Word32
deriving (Era -> Era -> Bool
(Era -> Era -> Bool) -> (Era -> Era -> Bool) -> Eq Era
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Era -> Era -> Bool
== :: Era -> Era -> Bool
$c/= :: Era -> Era -> Bool
/= :: Era -> Era -> Bool
Eq, Eq Era
Eq Era =>
(Era -> Era -> Ordering)
-> (Era -> Era -> Bool)
-> (Era -> Era -> Bool)
-> (Era -> Era -> Bool)
-> (Era -> Era -> Bool)
-> (Era -> Era -> Era)
-> (Era -> Era -> Era)
-> Ord Era
Era -> Era -> Bool
Era -> Era -> Ordering
Era -> Era -> Era
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Era -> Era -> Ordering
compare :: Era -> Era -> Ordering
$c< :: Era -> Era -> Bool
< :: Era -> Era -> Bool
$c<= :: Era -> Era -> Bool
<= :: Era -> Era -> Bool
$c> :: Era -> Era -> Bool
> :: Era -> Era -> Bool
$c>= :: Era -> Era -> Bool
>= :: Era -> Era -> Bool
$cmax :: Era -> Era -> Era
max :: Era -> Era -> Era
$cmin :: Era -> Era -> Era
min :: Era -> Era -> Era
Ord, Int -> Era -> ShowS
[Era] -> ShowS
Era -> String
(Int -> Era -> ShowS)
-> (Era -> String) -> ([Era] -> ShowS) -> Show Era
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Era -> ShowS
showsPrec :: Int -> Era -> ShowS
$cshow :: Era -> String
show :: Era -> String
$cshowList :: [Era] -> ShowS
showList :: [Era] -> ShowS
Show)
instance Decode Era where
get :: Get Era
get = do
Word8
first <- Get Word8
forall a. Decode a => Get a
get
case Word8
first :: Word8 of
Word8
0 -> Era -> Get Era
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return Era
ImmortalEra
Word8
_ -> Word8 -> Word8 -> Era
decodeMortal Word8
first (Word8 -> Era) -> Get Word8 -> Get Era
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
forall a. Decode a => Get a
get
where
decodeMortal :: Word8 -> Word8 -> Era
decodeMortal :: Word8 -> Word8 -> Era
decodeMortal Word8
first Word8
second =
let first' :: Word16
first' = Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
first
second' :: Word16
second' = Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
second
in Word16 -> Era
new_mortal_compact (Word16
first' Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
+ Word16
second' Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`shiftL` Int
8)
instance Encode Era where
put :: Putter Era
put Era
ImmortalEra = Putter Word8
forall a. Encode a => Putter a
put (Word8
0 :: Word8)
put (MortalEra Word32
period' Word32
phase') = Putter Word16
forall a. Encode a => Putter a
put Word16
encoded
where
encoded :: Word16
encoded :: Word16
encoded = Word16
first Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Word16
second
first :: Word16
first = (Word16
1 Word16 -> Word16 -> Word16
forall a. Ord a => a -> a -> a
`max` (Word16 -> Word16
forall a. Integral a => a -> a
trailing_zeros Word16
period Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
- Word16
1)) Word16 -> Word16 -> Word16
forall a. Ord a => a -> a -> a
`min` Word16
15
second :: Word16
second = (Word16
phase Word16 -> Word16 -> Word16
forall a. Integral a => a -> a -> a
`div` Word16
quantizeFactor) Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`shiftL` Int
4
quantizeFactor :: Word16
quantizeFactor = Word16 -> Word16 -> Word16
forall a. Ord a => a -> a -> a
max (Word16
period Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`shiftR` Int
12) Word16
1
period :: Word16
period = Word32 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
period'
phase :: Word16
phase = Word32 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
phase'
new_mortal_compact :: Word16 -> Era
new_mortal_compact :: Word16 -> Era
new_mortal_compact Word16
raw = Word32 -> Word32 -> Era
MortalEra Word32
period Word32
phase
where
era :: Word32
era = Word16 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word32) -> Word16 -> Word32
forall a b. (a -> b) -> a -> b
$ Word16 -> Word16
byteSwap16 Word16
raw
period :: Word32
period = Word32
2 Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` (Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
era Word32 -> Word32 -> Word32
forall a. Integral a => a -> a -> a
`rem` Word32
16))
quantizeFactor :: Word32
quantizeFactor = Word32 -> Word32 -> Word32
forall a. Ord a => a -> a -> a
max (Word32
period Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
12) Word32
1
phase :: Word32
phase = (Word32
era Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
4) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
quantizeFactor
trailing_zeros :: Integral a => a -> a
trailing_zeros :: forall a. Integral a => a -> a
trailing_zeros = (a -> a -> a) -> a -> [a] -> a
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl a -> a -> a
forall {a} {a}. (Integral a, Num a) => a -> a -> a
zero a
0 ([a] -> a) -> (a -> [a]) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0) ([a] -> [a]) -> (a -> [a]) -> a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a) -> a -> [a]
forall a. (a -> a) -> a -> [a]
iterate (a -> a -> a
forall a. Integral a => a -> a -> a
`div` a
2)
where
zero :: a -> a -> a
zero a
a a
x
| a
x a -> a -> a
forall a. Integral a => a -> a -> a
`mod` a
2 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 = a
a a -> a -> a
forall a. Num a => a -> a -> a
+ a
1
| Bool
otherwise = a
a
birth :: (Integral a, Integral b) => Era -> a -> b
birth :: forall a b. (Integral a, Integral b) => Era -> a -> b
birth Era
ImmortalEra a
_ = b
0
birth (MortalEra Word32
period Word32
phase) a
current = Word32 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> b) -> Word32 -> b
forall a b. (a -> b) -> a -> b
$
(Word32 -> Word32 -> Word32
forall a. Ord a => a -> a -> a
max (a -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
current) Word32
phase Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
phase) Word32 -> Word32 -> Word32
forall a. Integral a => a -> a -> a
`div` Word32
period Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
period Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
phase
death :: (Integral a, Integral b, Bounded b) => Era -> a -> b
death :: forall a b. (Integral a, Integral b, Bounded b) => Era -> a -> b
death Era
ImmortalEra a
_ = b
forall a. Bounded a => a
maxBound
death e :: Era
e@(MortalEra Word32
period Word32
_) a
current = Word32 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> b) -> Word32 -> b
forall a b. (a -> b) -> a -> b
$ Era -> a -> Word32
forall a b. (Integral a, Integral b) => Era -> a -> b
birth Era
e a
current Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
period