web3-0.8.0.0: src/Network/Ethereum/Account/Safe.hs
{-# LANGUAGE FlexibleContexts #-}
-- |
-- Module : Network.Ethereum.Account.Safe
-- Copyright : Alexander Krupenkin 2018
-- License : BSD3
--
-- Maintainer : mail@akru.me
-- Stability : experimental
-- Portability : unportable
--
-- Safe sending of Ethereum transaction.
--
module Network.Ethereum.Account.Safe where
import Control.Concurrent (threadDelay)
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans (lift)
import Network.Ethereum.Account.Class (Account (send))
import Network.Ethereum.Account.Internal (updateReceipt)
import qualified Network.Ethereum.Api.Eth as Eth
import Network.Ethereum.Api.Types (TxReceipt (receiptBlockNumber))
import Network.Ethereum.Contract.Method (Method)
import Network.JsonRpc.TinyClient (JsonRpc)
-- | Safe version of 'send' function of 'Account' typeclass
-- Waiting for some blocks of transaction confirmation before return
safeSend :: (Account p t, JsonRpc m, Method args, Monad (t m))
=> Integer
-- ^ Confirmation in blocks
-> args
-- ^ Contract method arguments
-> t m TxReceipt
-- ^ Receipt of sended transaction
safeSend b a = lift . waiting =<< send a
where
waiting receipt =
case receiptBlockNumber receipt of
Nothing -> do
liftIO $ threadDelay 1000000
waiting =<< updateReceipt receipt
Just bn -> do
current <- Eth.blockNumber
if current - bn >= fromInteger b
then return receipt
else do liftIO $ threadDelay 1000000
waiting receipt
-- | Count block confirmation to keep secure
-- According to Vitalik post
-- https://blog.ethereum.org/2015/09/14/on-slow-and-fast-block-times/
safeConfirmations :: Integer
safeConfirmations = 10