{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad (replicateM, void, (>=>))
import Data.Text (Text)
import Data.Word (Word64)
import Network.Haskoin.Address (Address (..), addrToString,
pubKeyAddr)
import Network.Haskoin.Block (Block (..), BlockHash,
BlockHeader)
import Network.Haskoin.Constants (btcTest)
import Network.Haskoin.Crypto (Hash160, SecKey)
import Network.Haskoin.Keys (PubKeyI, derivePubKeyI, secKey,
wrapSecKey)
import Network.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.Regtest (NodeHandle, withBitcoind)
import qualified Bitcoin.Core.Regtest as R
import Bitcoin.Core.RPC
main :: IO ()
main
= defaultMain . testCase "bitcoind-rpc" . withBitcoind 8449
$ bitcoindTests
[ testRpc "generatetoaddress" testGenerate
, testRpc "getbestblockhash" getBestBlockHash
, testRpc "getblockhash" $ getBlockHash 1
, 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 = addrToString btcTest addr
testBlock :: BitcoindClient Block
testBlock = getBestBlockHash >>= getBlock
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