module PaymentChannel.Internal.Receiver.Util
( updState
, mkExtendedDerivRpc
, metaKeyIndex
, setChannelStatus
, getChannelStatus
, markAsBusy
, isReadyForPayment
, checkChannelStatus
, getClosingPayment
, calcNewData
, updateMetadata
, module PaymentChannel.Internal.Receiver.Types
, module PaymentChannel.Internal.Class.Value
)
where
import PaymentChannel.Internal.Class.Value
import PaymentChannel.Internal.Receiver.Types
import qualified PaymentChannel.Internal.Settlement.Util as Settle
import PaymentChannel.Internal.Error
import PaymentChannel.Internal.Payment
import PaymentChannel.Internal.Metadata.Util
import PaymentChannel.Internal.Class.Value (HasValue(..))
import qualified Network.Haskoin.Crypto as HC
updState :: ServerPayChanG kd sd -> SignedPayment -> ServerPayChanG kd BtcSig
updState rpc p =
rpc { rpcState = replacePayment (rpcState rpc) p }
where
replacePayment state p' = state { pcsPayment = p' }
mkExtendedKeyRPC :: ServerPayChanI kd -> ExtPub -> Maybe ServerPayChanX
mkExtendedKeyRPC rpc@(MkServerPayChan pcs _) xpk =
if getKey xpk == getPubKey (getRecvPubKey pcs) then
Just $ mkExtendedKeyRPCUnsafe xpk rpc
else
Nothing
mkExtendedDerivRpc :: RootPub -> ServerPayChanI kd -> Maybe ServerPayChanX
mkExtendedDerivRpc rootPub spc =
if derivedChanParams == chanParams
then Just $ setKeyMetadata_ spc xPub
else Nothing
where
(derivedChanParams,xPub) = deriveRecvPub rootPub chanParams
chanParams = pairRedeemScript . pcsPayment . rpcState $ spc
mkExtendedKeyRPCUnsafe :: ExtPub -> ServerPayChanI kd -> ServerPayChanX
mkExtendedKeyRPCUnsafe xPub rpc =
rpc {
rpcMetadata =
Metadata xPub 0 [] (valueOf $ rpcState rpc) ReadyForPayment
}
metaKeyIndex :: ServerPayChanI KeyDeriveIndex -> KeyDeriveIndex
metaKeyIndex = mdKeyData . rpcMetadata
setKeyMetadata_ :: ServerPayChanG a sd -> b -> ServerPayChanG b sd
setKeyMetadata_ sp@MkServerPayChan{..} kd =
sp { rpcMetadata =
rpcMetadata { mdKeyData = kd }
}
setChannelStatus :: PayChanStatus -> ServerPayChanG kd sd -> ServerPayChanG kd sd
setChannelStatus s pcs@MkServerPayChan{ rpcMetadata = meta } =
pcs { rpcMetadata = metaSetStatus s meta }
getChannelStatus :: ServerPayChanG kd sd -> PayChanStatus
getChannelStatus MkServerPayChan{ rpcMetadata = meta } =
metaGetStatus meta
markAsBusy :: ServerPayChanG kd sd -> ServerPayChanG kd sd
markAsBusy = setChannelStatus PaymentInProgress
isReadyForPayment :: ServerPayChanG kd sd -> Bool
isReadyForPayment =
(== ReadyForPayment) . getChannelStatus
checkChannelStatus :: ServerPayChanG kd sd -> Either PayChanError (ServerPayChanG kd sd)
checkChannelStatus rpc =
maybe
(Right rpc)
(Left . StatusError)
(checkReadyForPayment $ getChannelStatus rpc)
getClosingPayment :: ServerPayChanI kd -> Maybe SignedPayment
getClosingPayment spc =
case getChannelStatus spc of
ChannelClosed p -> Just p
_ -> Nothing
calcNewData :: MetadataI a -> PayChanState BtcSig -> MetadataI a
calcNewData md@Metadata{ mdUnsettledValue = oldValRecvd, mdPayCount = oldCount } pcs =
md { mdUnsettledValue = checkedVal, mdPayCount = oldCount+1 }
where checkedVal = if newValRecvd < oldValRecvd then error "BUG: Value lost :(" else newValRecvd
newValRecvd = valueOf pcs
updateMetadata :: ServerPayChanI kd -> ServerPayChanI kd
updateMetadata rpc@MkServerPayChan{..} =
rpc { rpcMetadata = calcNewData rpcMetadata rpcState }