{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad (replicateM, void, (>=>))
import Data.Text (Text)
import Data.Word (Word64)
import Haskoin.Address (Address (..), addrToText, pubKeyAddr)
import Haskoin.Block (Block (..), BlockHash)
import Haskoin.Constants (btcTest)
import Haskoin.Crypto (Hash160, SecKey)
import Haskoin.Keys (
PubKeyI,
derivePubKeyI,
secKey,
wrapSecKey,
)
import Haskoin.Transaction (OutPoint (..), Tx (..), TxHash, txHash)
import Network.HTTP.Client (defaultManagerSettings, newManager)
import Test.Tasty (defaultMain)
import Test.Tasty.HUnit (assertFailure, testCase)
import Bitcoin.Core.RPC
import Bitcoin.Core.Regtest (NodeHandle, withBitcoind)
import qualified Bitcoin.Core.Regtest as R
main :: IO ()
main =
defaultMain . testCase "bitcoind-rpc" . withBitcoind 8449 $
bitcoindTests
[ testRpc "generatetoaddress" testGenerate
, testRpc "getbestblockhash" getBestBlockHash
, testRpc "getblockhash" $ getBlockHash 1
, testRpc "getblockfilter" $ testBlockFilter
, testRpc "getblockheader" testBlockHeader
, testRpc "getblock" testBlock
, testRpc "getblockcount" getBlockCount
, testRpc "getdifficulty" getDifficulty
, testRpc "getchaintips" getChainTips
, testRpc "getchaintxstats" $ getChainTxStats Nothing Nothing
, testRpc "getmempoolinfo" getMempoolInfo
, testRpc "getrawmempool" getRawMempool
, testRpc "getrawtransaction" testGetTransaction
, testRpc "sendrawtransaction" testSendTransaction
, testRpc "createOutput" testCreateOutput
, testRpc "getmempoolancestors" testMempoolAncestors
, testRpc "getmempooldescendants" testMempoolDescendants
, testRpc "getpeerinfo" getPeerInfo
, testRpc "getconnectioncount" getConnectionCount
, testRpc "getnodeaddresses" $ getNodeAddresses (Just 10)
, testRpc "getaddednodeinfo" $ getAddedNodeInfo Nothing
, testRpc "listbanned" listBanned
, testRpc "getnettotals" getNetTotals
, testRpc "uptime" uptime
, testRpc "addnode" $ addNode "127.0.0.1:8448" Add
, testRpc "clearbanned" clearBanned
]
testGenerate :: BitcoindClient [BlockHash]
testGenerate = generateToAddress 120 addrText Nothing
key :: SecKey
Just key = secKey "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
pk :: PubKeyI
pk = derivePubKeyI $ wrapSecKey True key
addr :: Address
addrHash :: Hash160
addr@(PubKeyAddress addrHash) = pubKeyAddr pk
addrText :: Text
Just addrText = addrToText btcTest addr
testBlock :: BitcoindClient Block
testBlock = getBestBlockHash >>= getBlock
testBlockFilter :: BitcoindClient CompactFilter
testBlockFilter = getBestBlockHash >>= getBlockFilter
testBlockHeader :: BitcoindClient BlockHeader
testBlockHeader = getBestBlockHash >>= getBlockHeader
testBlockStats :: BitcoindClient BlockStats
testBlockStats = getBestBlockHash >>= getBlockStats
testGetTransaction :: BitcoindClient Tx
testGetTransaction =
getBestBlockHash >>= getBlock >>= (`getTransaction` Nothing) . txHash . head . blockTxns
testSendTransaction :: BitcoindClient TxHash
testSendTransaction = do
outp <- head <$> replicateM 101 R.generate
let Right (tx, _) = R.spendPackageOutputs [outp] (R.addrs !! 3) R.oneBitcoin
sendTransaction tx Nothing
testMempoolAncestors :: BitcoindClient [TxHash]
testMempoolAncestors = testSendTransaction >>= getMempoolAncestors
testMempoolDescendants :: BitcoindClient [TxHash]
testMempoolDescendants = testSendTransaction >>= getMempoolAncestors
testCreateOutput :: BitcoindClient (OutPoint, Word64)
testCreateOutput = R.createOutput (R.addrs !! 4) (2 * R.oneBitcoin)
testRpc :: String -> BitcoindClient r -> (String, BitcoindClient ())
testRpc name x = (name, void x)
bitcoindTests :: [(String, BitcoindClient ())] -> NodeHandle -> IO ()
bitcoindTests ts h = do
mgr <- newManager defaultManagerSettings
let run msg = R.runBitcoind mgr h >=> assertRight msg
mapM_ (uncurry run) ts
assertRight :: Show a => String -> Either a b -> IO b
assertRight msg = either onFail return
where
onFail e = assertFailure $ msg <> " - " <> show e