{-# OPTIONS_HADDOCK prune #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
module Lightning.Protocol.BOLT3.Scripts (
funding_script
, funding_witness
, to_local_script
, to_local_witness_spend
, to_local_witness_revoke
, to_remote_script
, to_remote_witness
, anchor_script
, anchor_witness_owner
, anchor_witness_anyone
, offered_htlc_script
, offered_htlc_witness_preimage
, offered_htlc_witness_revoke
, received_htlc_script
, received_htlc_witness_timeout
, received_htlc_witness_revoke
, htlc_output_script
, htlc_output_witness_spend
, htlc_output_witness_revoke
, to_p2wsh
, witness_script_hash
) where
import Data.Bits ((.&.), shiftR)
import Data.Word (Word8, Word16, Word32)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Lazy as BSL
import qualified Crypto.Hash.SHA256 as SHA256
import qualified Crypto.Hash.RIPEMD160 as RIPEMD160
import Lightning.Protocol.BOLT3.Types
op_0 :: Word8
op_0 :: Word8
op_0 = Word8
0x00
op_if :: Word8
op_if :: Word8
op_if = Word8
0x63
op_notif :: Word8
op_notif :: Word8
op_notif = Word8
0x64
op_else :: Word8
op_else :: Word8
op_else = Word8
0x67
op_endif :: Word8
op_endif :: Word8
op_endif = Word8
0x68
op_drop :: Word8
op_drop :: Word8
op_drop = Word8
0x75
op_dup :: Word8
op_dup :: Word8
op_dup = Word8
0x76
op_swap :: Word8
op_swap :: Word8
op_swap = Word8
0x7c
op_size :: Word8
op_size :: Word8
op_size = Word8
0x82
op_equal :: Word8
op_equal :: Word8
op_equal = Word8
0x87
op_equalverify :: Word8
op_equalverify :: Word8
op_equalverify = Word8
0x88
op_ifdup :: Word8
op_ifdup :: Word8
op_ifdup = Word8
0x73
op_hash160 :: Word8
op_hash160 :: Word8
op_hash160 = Word8
0xa9
op_checksig :: Word8
op_checksig :: Word8
op_checksig = Word8
0xac
op_checksigverify :: Word8
op_checksigverify :: Word8
op_checksigverify = Word8
0xad
op_checkmultisig :: Word8
op_checkmultisig :: Word8
op_checkmultisig = Word8
0xae
op_checklocktimeverify :: Word8
op_checklocktimeverify :: Word8
op_checklocktimeverify = Word8
0xb1
op_checksequenceverify :: Word8
op_checksequenceverify :: Word8
op_checksequenceverify = Word8
0xb2
op_1 :: Word8
op_1 :: Word8
op_1 = Word8
0x51
op_2 :: Word8
op_2 :: Word8
op_2 = Word8
0x52
op_16 :: Word8
op_16 :: Word8
op_16 = Word8
0x60
push_data :: BS.ByteString -> BSB.Builder
push_data :: ByteString -> Builder
push_data !ByteString
bs
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
75 = Word8 -> Builder
BSB.word8 (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
BSB.byteString ByteString
bs
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
255 = Word8 -> Builder
BSB.word8 Word8
0x4c Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
BSB.byteString ByteString
bs
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
65535 = Word8 -> Builder
BSB.word8 Word8
0x4d Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word16 -> Builder
BSB.word16LE (Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
BSB.byteString ByteString
bs
| Bool
otherwise = Word8 -> Builder
BSB.word8 Word8
0x4e Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word32 -> Builder
BSB.word32LE (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
BSB.byteString ByteString
bs
where
!len :: Int
len = ByteString -> Int
BS.length ByteString
bs
{-# INLINE push_data #-}
push_csv_delay :: Word16 -> BSB.Builder
push_csv_delay :: Word16 -> Builder
push_csv_delay !Word16
n
| Word16
n Word16 -> Word16 -> Bool
forall a. Eq a => a -> a -> Bool
== Word16
0 = Word8 -> Builder
BSB.word8 Word8
op_0
| Word16
n Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word16
16 = Word8 -> Builder
BSB.word8 (Word8
0x50 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
n)
| Word16
n Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word16
0x7f = ByteString -> Builder
push_data (Word8 -> ByteString
BS.singleton (Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
n))
| Word16
n Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word16
0x7fff = ByteString -> Builder
push_data ([Word8] -> ByteString
BS.pack [Word8
lo, Word8
hi])
| Bool
otherwise = ByteString -> Builder
push_data ([Word8] -> ByteString
BS.pack [Word8
lo, Word8
hi, Word8
0x00])
where
!lo :: Word8
lo = Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16
n Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0xff)
!hi :: Word8
hi = Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Word16
n Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`shiftR` Int
8) Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0xff)
{-# INLINE push_csv_delay #-}
push_cltv :: Word32 -> BSB.Builder
push_cltv :: Word32 -> Builder
push_cltv !Word32
n
| Word32
n Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
0 = Word8 -> Builder
BSB.word8 Word8
op_0
| Word32
n Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word32
16 = Word8 -> Builder
BSB.word8 (Word8
0x50 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
n)
| Bool
otherwise = ByteString -> Builder
push_data (Word32 -> ByteString
encode_scriptnum Word32
n)
where
encode_scriptnum :: Word32 -> BS.ByteString
encode_scriptnum :: Word32 -> ByteString
encode_scriptnum Word32
0 = ByteString
BS.empty
encode_scriptnum !Word32
v =
let
go :: Word32 -> [Word8]
go :: Word32 -> [Word8]
go Word32
0 = []
go !Word32
x = Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
x Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0xff) Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: Word32 -> [Word8]
go (Word32
x Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
8)
!bytes :: [Word8]
bytes = Word32 -> [Word8]
go Word32
v
!result :: [Word8]
result = case [Word8] -> [Word8]
forall a. [a] -> [a]
reverse [Word8]
bytes of
[] -> [Word8]
bytes
(Word8
msb:[Word8]
_) | Word8
msb Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x80 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
0 -> [Word8]
bytes [Word8] -> [Word8] -> [Word8]
forall a. [a] -> [a] -> [a]
++ [Word8
0x00]
[Word8]
_ -> [Word8]
bytes
in [Word8] -> ByteString
BS.pack [Word8]
result
{-# INLINE push_cltv #-}
build_script :: BSB.Builder -> Script
build_script :: Builder -> Script
build_script = ByteString -> Script
Script (ByteString -> Script)
-> (Builder -> ByteString) -> Builder -> Script
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LazyByteString -> ByteString
BSL.toStrict (LazyByteString -> ByteString)
-> (Builder -> LazyByteString) -> Builder -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyByteString
BSB.toLazyByteString
{-# INLINE build_script #-}
hash160 :: BS.ByteString -> BS.ByteString
hash160 :: ByteString -> ByteString
hash160 = ByteString -> ByteString
RIPEMD160.hash (ByteString -> ByteString)
-> (ByteString -> ByteString) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
SHA256.hash
{-# INLINE hash160 #-}
witness_script_hash :: Script -> BS.ByteString
witness_script_hash :: Script -> ByteString
witness_script_hash (Script !ByteString
s) = ByteString -> ByteString
SHA256.hash ByteString
s
{-# INLINE witness_script_hash #-}
to_p2wsh :: Script -> Script
to_p2wsh :: Script -> Script
to_p2wsh !Script
script =
let !h :: ByteString
h = Script -> ByteString
witness_script_hash Script
script
in Builder -> Script
build_script (Word8 -> Builder
BSB.word8 Word8
op_0 Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
h)
{-# INLINE to_p2wsh #-}
funding_script :: FundingPubkey -> FundingPubkey -> Script
funding_script :: FundingPubkey -> FundingPubkey -> Script
funding_script (FundingPubkey (Pubkey !ByteString
pk1)) (FundingPubkey (Pubkey !ByteString
pk2)) =
let (!ByteString
lesser, !ByteString
greater) = if ByteString
pk1 ByteString -> ByteString -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteString
pk2 then (ByteString
pk1, ByteString
pk2) else (ByteString
pk2, ByteString
pk1)
in Builder -> Script
build_script (Builder -> Script) -> Builder -> Script
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
BSB.word8 Word8
op_2
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
lesser
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
greater
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_2
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checkmultisig
funding_witness :: BS.ByteString -> BS.ByteString -> Witness
funding_witness :: ByteString -> ByteString -> Witness
funding_witness !ByteString
sig1 !ByteString
sig2 = [ByteString] -> Witness
Witness [ByteString
BS.empty, ByteString
sig1, ByteString
sig2]
to_local_script
:: RevocationPubkey
-> ToSelfDelay
-> LocalDelayedPubkey
-> Script
to_local_script :: RevocationPubkey -> ToSelfDelay -> LocalDelayedPubkey -> Script
to_local_script
(RevocationPubkey (Pubkey !ByteString
revpk))
(ToSelfDelay !Word16
delay)
(LocalDelayedPubkey (Pubkey !ByteString
localpk)) =
Builder -> Script
build_script (Builder -> Script) -> Builder -> Script
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
BSB.word8 Word8
op_if
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
revpk
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_else
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word16 -> Builder
push_csv_delay Word16
delay
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksequenceverify
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_drop
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
localpk
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_endif
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksig
to_local_witness_spend :: BS.ByteString -> Witness
to_local_witness_spend :: ByteString -> Witness
to_local_witness_spend !ByteString
sig = [ByteString] -> Witness
Witness [ByteString
sig, ByteString
BS.empty]
to_local_witness_revoke :: BS.ByteString -> Witness
to_local_witness_revoke :: ByteString -> Witness
to_local_witness_revoke !ByteString
sig = [ByteString] -> Witness
Witness [ByteString
sig, Word8 -> ByteString
BS.singleton Word8
0x01]
to_remote_script :: RemotePubkey -> ChannelFeatures -> Script
to_remote_script :: RemotePubkey -> ChannelFeatures -> Script
to_remote_script (RemotePubkey (Pubkey !ByteString
pk)) !ChannelFeatures
features
| ChannelFeatures -> Bool
has_anchors ChannelFeatures
features =
Builder -> Script
build_script (Builder -> Script) -> Builder -> Script
forall a b. (a -> b) -> a -> b
$
ByteString -> Builder
push_data ByteString
pk
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksigverify
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_1
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksequenceverify
| Bool
otherwise =
let !h :: ByteString
h = ByteString -> ByteString
hash160 ByteString
pk
in Builder -> Script
build_script (Word8 -> Builder
BSB.word8 Word8
op_0 Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
h)
to_remote_witness :: BS.ByteString -> RemotePubkey -> ChannelFeatures -> Witness
to_remote_witness :: ByteString -> RemotePubkey -> ChannelFeatures -> Witness
to_remote_witness !ByteString
sig (RemotePubkey (Pubkey !ByteString
pk)) !ChannelFeatures
features
| ChannelFeatures -> Bool
has_anchors ChannelFeatures
features = [ByteString] -> Witness
Witness [ByteString
sig]
| Bool
otherwise = [ByteString] -> Witness
Witness [ByteString
sig, ByteString
pk]
anchor_script :: FundingPubkey -> Script
anchor_script :: FundingPubkey -> Script
anchor_script (FundingPubkey (Pubkey !ByteString
pk)) =
Builder -> Script
build_script (Builder -> Script) -> Builder -> Script
forall a b. (a -> b) -> a -> b
$
ByteString -> Builder
push_data ByteString
pk
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksig
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_ifdup
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_notif
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_16
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksequenceverify
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_endif
anchor_witness_owner :: BS.ByteString -> Witness
anchor_witness_owner :: ByteString -> Witness
anchor_witness_owner !ByteString
sig = [ByteString] -> Witness
Witness [ByteString
sig]
anchor_witness_anyone :: Witness
anchor_witness_anyone :: Witness
anchor_witness_anyone = [ByteString] -> Witness
Witness [ByteString
BS.empty]
offered_htlc_script
:: RevocationPubkey
-> RemoteHtlcPubkey
-> LocalHtlcPubkey
-> PaymentHash
-> ChannelFeatures
-> Script
offered_htlc_script :: RevocationPubkey
-> RemoteHtlcPubkey
-> LocalHtlcPubkey
-> PaymentHash
-> ChannelFeatures
-> Script
offered_htlc_script
(RevocationPubkey (Pubkey !ByteString
revpk))
(RemoteHtlcPubkey (Pubkey !ByteString
remotepk))
(LocalHtlcPubkey (Pubkey !ByteString
localpk))
(PaymentHash !ByteString
ph)
!ChannelFeatures
features =
let !revpk_hash :: ByteString
revpk_hash = ByteString -> ByteString
hash160 ByteString
revpk
!payment_hash160 :: ByteString
payment_hash160 = ByteString -> ByteString
RIPEMD160.hash ByteString
ph
!csv_suffix :: Builder
csv_suffix = if ChannelFeatures -> Bool
has_anchors ChannelFeatures
features
then Word8 -> Builder
BSB.word8 Word8
op_1
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksequenceverify
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_drop
else Builder
forall a. Monoid a => a
mempty
in Builder -> Script
build_script (Builder -> Script) -> Builder -> Script
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
BSB.word8 Word8
op_dup
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_hash160
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
revpk_hash
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_equal
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_if
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksig
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_else
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
remotepk
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_swap
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_size
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data (Word8 -> ByteString
BS.singleton Word8
32)
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_equal
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_notif
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_drop
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_2
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_swap
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
localpk
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_2
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checkmultisig
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_else
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_hash160
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
payment_hash160
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_equalverify
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksig
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_endif
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
csv_suffix
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_endif
offered_htlc_witness_preimage
:: BS.ByteString -> PaymentPreimage -> Witness
offered_htlc_witness_preimage :: ByteString -> PaymentPreimage -> Witness
offered_htlc_witness_preimage !ByteString
sig (PaymentPreimage !ByteString
preimage) =
[ByteString] -> Witness
Witness [ByteString
sig, ByteString
preimage]
offered_htlc_witness_revoke :: BS.ByteString -> Pubkey -> Witness
offered_htlc_witness_revoke :: ByteString -> Pubkey -> Witness
offered_htlc_witness_revoke !ByteString
sig (Pubkey !ByteString
revpk) = [ByteString] -> Witness
Witness [ByteString
sig, ByteString
revpk]
received_htlc_script
:: RevocationPubkey
-> RemoteHtlcPubkey
-> LocalHtlcPubkey
-> PaymentHash
-> CltvExpiry
-> ChannelFeatures
-> Script
received_htlc_script :: RevocationPubkey
-> RemoteHtlcPubkey
-> LocalHtlcPubkey
-> PaymentHash
-> CltvExpiry
-> ChannelFeatures
-> Script
received_htlc_script
(RevocationPubkey (Pubkey !ByteString
revpk))
(RemoteHtlcPubkey (Pubkey !ByteString
remotepk))
(LocalHtlcPubkey (Pubkey !ByteString
localpk))
(PaymentHash !ByteString
ph)
(CltvExpiry !Word32
expiry)
!ChannelFeatures
features =
let !revpk_hash :: ByteString
revpk_hash = ByteString -> ByteString
hash160 ByteString
revpk
!payment_hash160 :: ByteString
payment_hash160 = ByteString -> ByteString
RIPEMD160.hash ByteString
ph
!csv_suffix :: Builder
csv_suffix = if ChannelFeatures -> Bool
has_anchors ChannelFeatures
features
then Word8 -> Builder
BSB.word8 Word8
op_1
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksequenceverify
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_drop
else Builder
forall a. Monoid a => a
mempty
in Builder -> Script
build_script (Builder -> Script) -> Builder -> Script
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
BSB.word8 Word8
op_dup
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_hash160
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
revpk_hash
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_equal
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_if
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksig
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_else
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
remotepk
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_swap
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_size
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data (Word8 -> ByteString
BS.singleton Word8
32)
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_equal
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_if
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_hash160
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
payment_hash160
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_equalverify
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_2
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_swap
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
push_data ByteString
localpk
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_2
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checkmultisig
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_else
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_drop
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word32 -> Builder
push_cltv Word32
expiry
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checklocktimeverify
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_drop
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_checksig
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_endif
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
csv_suffix
Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
BSB.word8 Word8
op_endif
received_htlc_witness_timeout :: BS.ByteString -> Witness
received_htlc_witness_timeout :: ByteString -> Witness
received_htlc_witness_timeout !ByteString
sig = [ByteString] -> Witness
Witness [ByteString
sig, ByteString
BS.empty]
received_htlc_witness_revoke :: BS.ByteString -> Pubkey -> Witness
received_htlc_witness_revoke :: ByteString -> Pubkey -> Witness
received_htlc_witness_revoke !ByteString
sig (Pubkey !ByteString
revpk) = [ByteString] -> Witness
Witness [ByteString
sig, ByteString
revpk]
htlc_output_script
:: RevocationPubkey
-> ToSelfDelay
-> LocalDelayedPubkey
-> Script
htlc_output_script :: RevocationPubkey -> ToSelfDelay -> LocalDelayedPubkey -> Script
htlc_output_script = RevocationPubkey -> ToSelfDelay -> LocalDelayedPubkey -> Script
to_local_script
htlc_output_witness_spend :: BS.ByteString -> Witness
htlc_output_witness_spend :: ByteString -> Witness
htlc_output_witness_spend = ByteString -> Witness
to_local_witness_spend
htlc_output_witness_revoke :: BS.ByteString -> Witness
htlc_output_witness_revoke :: ByteString -> Witness
htlc_output_witness_revoke = ByteString -> Witness
to_local_witness_revoke