Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: wraithm/network-bitcoin
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: bitnomial/network-bitcoin
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Able to merge. These branches can be automatically merged.

Commits on Aug 17, 2018

  1. Fixing cabal errors

    wraithm committed Aug 17, 2018
    Copy the full SHA
    48a4c2f View commit details

Commits on Dec 18, 2018

  1. Copy the full SHA
    42f175a View commit details

Commits on Jan 22, 2019

  1. Copy the full SHA
    dbd384d View commit details

Commits on Mar 5, 2019

  1. Copy the full SHA
    8192e50 View commit details

Commits on Mar 6, 2019

  1. hlint

    GambolingPangolin committed Mar 6, 2019
    Copy the full SHA
    de8f14a View commit details
  2. Copy the full SHA
    6a03ead View commit details
  3. adds some tests

    GambolingPangolin committed Mar 6, 2019
    Copy the full SHA
    91d812f View commit details

Commits on Mar 7, 2019

  1. updates:

    - removes incorrect field from estimateSmartFee return value
    - updates OutputInfo for v0.17
    GambolingPangolin committed Mar 7, 2019
    Copy the full SHA
    22984ab View commit details
  2. hlint

    GambolingPangolin committed Mar 7, 2019
    Copy the full SHA
    753932d View commit details
  3. Copy the full SHA
    d14e796 View commit details
  4. Copy the full SHA
    9959246 View commit details
  5. cleanup

    GambolingPangolin committed Mar 7, 2019
    Copy the full SHA
    d89ab1d View commit details
  6. Merge pull request #1 from GambolingPangolin/master

    estimateSmartFee & updates
    wraithm authored Mar 7, 2019
    Copy the full SHA
    0ac2fbc View commit details
  7. version bump

    GambolingPangolin authored Mar 7, 2019
    Copy the full SHA
    fce34a3 View commit details

Commits on Mar 11, 2019

  1. Copy the full SHA
    d5886eb View commit details
  2. Merge pull request #2 from GambolingPangolin/master

    bug fix in estimateSmartFee
    wraithm authored Mar 11, 2019
    Copy the full SHA
    4b5f5cb View commit details

Commits on Aug 5, 2019

  1. Copy the full SHA
    2cb909d View commit details
  2. whitespace

    GambolingPangolin committed Aug 5, 2019
    Copy the full SHA
    67b27fa View commit details
  3. Merge pull request cgaebel#3 from GambolingPangolin/master

    removes deprecated rpc call 'generate'
    wraithm authored Aug 5, 2019
    Copy the full SHA
    40057a2 View commit details

Commits on Aug 26, 2019

  1. updates generate command

    restores compatibility with older nodes
    GambolingPangolin committed Aug 26, 2019
    Copy the full SHA
    e00641b View commit details
  2. Merge pull request cgaebel#4 from GambolingPangolin/master

    updates generate command
    wraithm authored Aug 26, 2019
    Copy the full SHA
    17af259 View commit details
  3. Copy the full SHA
    286a257 View commit details
  4. Merge pull request cgaebel#5 from GambolingPangolin/master

    fixes status code in generate rpc call
    wraithm authored Aug 26, 2019
    Copy the full SHA
    f630f02 View commit details

Commits on Dec 22, 2019

  1. Upgrade GHC

    wraithm committed Dec 22, 2019
    Copy the full SHA
    476b19f View commit details
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -6,7 +6,9 @@
.project
Setup.hs
dist/
dist-newstyle/
cabal-dev/
network-bitcoin-tests
cabal.sandbox.config
.cabal-sandbox/
.stack-work
tags
9 changes: 3 additions & 6 deletions .hgignore
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
syntax: regexp
\#.*\#$
\.\#
\.sw[op]
\.DS_Store$
\.cabal-sandbox/
\.vagrant/
\.hpc/
\.tix$
cabal\.sandbox\.config$
\.shake\.database$
\.shake/
dist/
\.tfstate\.backup$
\.tfstate\.blank$
\.terraform/
dist-newstyle/
\.stack-work/
^tags$
13 changes: 13 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
1.9.1

* tries to call 'generate' before falling back to 'generatetoaddress'

1.9.0

* removes 'generate' rpc call
* adds test case for 'generateToAddress' and updates tests

1.8.5

* ...

1.1.0

* Added missing HashData fields
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,19 @@
See the [Hackage documentation](http://hackage.haskell.org/package/network-bitcoin)
network-bitcoin
====

This library supports [Bitcoin Core][1] `v0.18` only.

See the [Hackage documentation][2].

Testing
----

The tests expect to run against a `bitcoind` node running in regtest mode.
Invoke `bitcoind` with:

```shell
$ bitcoind -regtest -rpcuser=bitcoinrpc -rpcpassword=bitcoinrpcpassword -rpcport=18444
```

[1]: https://github.com/bitcoin/bitcoin
[2]: http://hackage.haskell.org/package/network-bitcoin
27 changes: 12 additions & 15 deletions network-bitcoin.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: network-bitcoin
Version: 1.8.3
Version: 1.9.1
Synopsis: An interface to bitcoind.
Description:
This can be used to send Bitcoins, query balances, etc. It
@@ -9,29 +9,25 @@ Description:
> import Network.Bitcoin
>
> main = do
> balance <- getBalance auth
> client <- getClient "http://127.0.0.1:8332" "user" "password"
> balance <- getBalance client
> putStrLn $ show balance ++ " BTC"
> where
> auth = Auth "http://127.0.0.1:8332" "user" "password"
.
To learn more about Bitcoin, see <http://www.bitcoin.org>.
License: BSD3
License-file: LICENSE
Author: Michael Hendricks <michael@ndrix.org>
Clark Gaebel <cgaebel@uwaterloo.ca>
Maintainer: Clark Gaebel <cgaebel@uwaterloo.ca>
Stability: experimental
Homepage: http://github.com/wowus/network-bitcoin
Bug-reports: http://github.com/wowus/network-bitcoin/issues
Maintainer: Matt Wraith <matt@bitnomial.com>
Homepage: http://github.com/bitnomial/network-bitcoin
Bug-reports: http://github.com/bitnomial/network-bitcoin/issues
Copyright: 2012 Michael Hendricks <michael@ndrix.org>
2013 Clark Gaebel <cgaebel@uwaterloo.ca>
Stability: experimental
Homepage: http://github.com/mndrix/network-bitcoin
Bug-reports: http://github.com/wowus/network-bitcoin/issues
Category: Network
Build-type: Simple
Cabal-version: >=1.8
tested-with: GHC ==7.4.1, GHC ==7.6.2, GHC ==7.6.3
tested-with: GHC ==8.4.3

Library
hs-source-dirs: src
@@ -66,12 +62,11 @@ Library

Source-repository head
type: git
location: git://github.com/wowus/network-bitcoin.git
location: git://github.com/bitnomial/network-bitcoin.git

Test-suite network-bitcoin-tests
hs-source-dirs: src
ghc-options: -Wall
main-is: Test/Main.hs
hs-source-dirs: src/Test
main-is: Main.hs
type: exitcode-stdio-1.0
build-depends:
aeson >= 0.8,
@@ -87,5 +82,7 @@ Test-suite network-bitcoin-tests
base == 4.*,
time >= 1.4.2,
QuickCheck >= 2.6,
tasty >= 1.0,
tasty-quickcheck >= 0.10,
http-client >= 0.4.6,
network-bitcoin
7 changes: 7 additions & 0 deletions src/Network/Bitcoin.hs
Original file line number Diff line number Diff line change
@@ -30,6 +30,8 @@ module Network.Bitcoin
, importPrivateKey
, dumpPrivateKey
-- * Mining Operations
, generate
, generateToAddress
, getGenerate
, setGenerate
, getHashesPerSec
@@ -47,6 +49,9 @@ module Network.Bitcoin
, getConnectionCount
, PeerInfo(..)
, getPeerInfo
, AddNodeCommand(..)
, addNode
, disconnectNode
-- * Raw Transaction Operations
, RawTransaction
, getRawTransaction
@@ -90,6 +95,8 @@ module Network.Bitcoin
, moveBitcoins
, sendFromAccount
, sendMany
, EstimationMode (..)
, estimateSmartFee
-- , createMultiSig
, ReceivedByAddress(..)
, listReceivedByAddress
26 changes: 19 additions & 7 deletions src/Network/Bitcoin/BlockChain.hs
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ module Network.Bitcoin.BlockChain ( Client
, setTransactionFee
, getRawMemoryPool
, BlockHash
, BlockHeight
, getBlockHash
, Block(..)
, getBlock
@@ -29,7 +30,7 @@ import Network.Bitcoin.Internal
import Network.Bitcoin.RawTransaction

-- | Returns the number of blocks in the longest block chain.
getBlockCount :: Client -> IO Integer
getBlockCount :: Client -> IO BlockHeight
getBlockCount client = callApi client "getblockcount" []

-- | Returns the proof-of-work difficulty as a multiple of the minimum
@@ -51,10 +52,11 @@ getRawMemoryPool client = callApi client "getrawmempool" []

-- | The hash of a given block.
type BlockHash = HexString
type BlockHeight = Integer

-- | Returns the hash of the block in best-block-chain at the given index.
getBlockHash :: Client
-> Integer -- ^ Block index.
-> BlockHeight -- ^ Block index.
-> IO BlockHash
getBlockHash client idx = callApi client "getblockhash" [ tj idx ]

@@ -65,7 +67,7 @@ data Block = Block { blockHash :: BlockHash
-- | The size of the block.
, blkSize :: Integer
-- | The "height" of the block. TODO: Clarify this.
, blkHeight :: Integer
, blkHeight :: BlockHeight
-- | The version of the block.
, blkVersion :: Integer
-- | The hash of the block at the root of the merkle tree
@@ -79,14 +81,21 @@ data Block = Block { blockHash :: BlockHash
, blkNonce :: Integer
, blkBits :: HexString
-- | How hard was this block to mine?
, blkDifficulty :: Integer
, blkDifficulty :: Double
-- | A pointer to the next block in the chain.
, nextBlock :: Maybe BlockHash
-- | A pointer to the previous block in the chain.
, prevBlock :: Maybe BlockHash
}
deriving ( Show, Read, Ord, Eq )

-- Missing from data type:
-- - strippedsize
-- - weight
-- - versionHex
-- - mediantime
-- - nTx
-- - chainwork
instance FromJSON Block where
parseJSON (Object o) = Block <$> o .: "hash"
<*> o .: "confirmations"
@@ -110,6 +119,8 @@ getBlock client bh = callApi client "getblock" [ tj bh ]
-- | Information on the unspent transaction in the output set.
data OutputSetInfo =
OutputSetInfo { osiBestBlock :: BlockHash
-- | The height of the best block chain
, osiHeight :: BlockHeight
-- | The number of transactions in the output set.
, numTransactions :: Integer
-- | The number of outputs for the transactions.
@@ -121,6 +132,7 @@ data OutputSetInfo =

instance FromJSON OutputSetInfo where
parseJSON (Object o) = OutputSetInfo <$> o .: "bestblock"
<*> o .: "height"
<*> o .: "transactions"
<*> o .: "txouts"
<*> o .: "bytes_serialized"
@@ -140,7 +152,7 @@ data OutputInfo =
-- | The public key of the sender.
, oiScriptPubKey :: ScriptPubKey
-- | The version of this transaction.
, oiVersion :: Integer
, oiVersion :: Maybe Integer
-- | Is this transaction part of the coin base?
, oiCoinBase :: Bool
}
@@ -151,13 +163,13 @@ instance FromJSON OutputInfo where
<*> o .: "confirmations"
<*> o .: "value"
<*> o .: "scriptPubKey"
<*> o .: "version"
<*> o .:? "version"
<*> o .: "coinbase"
parseJSON _ = mzero

-- | Returns details about an unspent transaction output.
getOutputInfo :: Client
-> TransactionID
-> Integer -- ^ The index we're looking at.
-> IO OutputInfo
-> IO (Maybe OutputInfo)
getOutputInfo client txid n = callApi client "gettxout" [ tj txid, tj n ]
14 changes: 7 additions & 7 deletions src/Network/Bitcoin/Internal.hs
Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@ getClient :: String
-> BS.ByteString
-> IO Client
getClient url user pass = do
url' <- parseUrl url
url' <- parseUrlThrow url
mgr <- newManager defaultManagerSettings
let baseReq = applyBasicAuth user pass url'
{ method = "POST"
@@ -101,9 +101,9 @@ callApi :: FromJSON v
callApi client cmd params = readVal =<< client jsonRpcReqBody
where
readVal bs = case decode' bs of
Just r@(BitcoinRpcResponse {btcError=NoError})
Just r@BitcoinRpcResponse {btcError=NoError}
-> return $ btcResult r
Just (BitcoinRpcResponse {btcError=BitcoinRpcError code msg})
Just BitcoinRpcResponse {btcError=BitcoinRpcError code msg}
-> throw $ BitcoinApiError code msg
Nothing
-> throw $ BitcoinResultTypeError bs
@@ -116,18 +116,18 @@ callApi client cmd params = readVal =<< client jsonRpcReqBody
{-# INLINE callApi #-}

-- | Used to allow "null" to decode to a tuple.
data Nil = Nil { unNil :: () }
newtype Nil = Nil { unNil :: () }

instance FromJSON Nil where
parseJSON Null = return $ Nil ()
parseJSON x = fail $ "\"null\" was expected, but " ++ show x ++ " was recieved."

-- | Used to parse "null" or [HexString]
data NilOrArray = NilOrArray {unArr :: Maybe [HexString]}
newtype NilOrArray = NilOrArray {unArr :: Maybe [HexString]}

instance FromJSON NilOrArray where
parseJSON Null = return $ NilOrArray Nothing
parseJSON a@(Array _) = liftM NilOrArray $ parseJSON a
parseJSON a@(Array _) = NilOrArray <$> parseJSON a
parseJSON x = fail $ "Expected \"null\" or array, but " ++ show x ++ " was recieved."

-- | A handy shortcut for toJSON, because I'm lazy.
@@ -140,7 +140,7 @@ tjm d m = tj $ fromMaybe d m
{-# INLINE tjm #-}

tja :: ToJSON a => Maybe a -> [Value]
tja m = fromMaybe [] $ pure . tj <$> m
tja = maybe [] (pure . tj)
{-# INLINE tja #-}

-- | A wrapper for a vector of address:amount pairs. The RPC expects that as
23 changes: 16 additions & 7 deletions src/Network/Bitcoin/Mining.hs
Original file line number Diff line number Diff line change
@@ -31,9 +31,15 @@ module Network.Bitcoin.Mining ( Client
, submitBlock
) where

import Control.Exception (catch, throw)
import Control.Monad
import Data.Aeson as A
import Network.Bitcoin.Internal
import Network.Bitcoin.Wallet (getNewAddress)
import Network.HTTP.Client (HttpException (..),
HttpExceptionContent (..),
responseStatus)
import Network.HTTP.Types (status500)

-- | Returns whether or not bitcoind is generating bitcoins.
getGenerate :: Client -- ^ bitcoind RPC client
@@ -70,10 +76,14 @@ generate :: Client
-> IO [HexString] -- ^ An array containing the block header
-- hashes of the generated blocks
-- (may be empty if used with generate 0)
generate client blocks Nothing =
callApi client "generate" [ tj blocks ]
generate client blocks (Just maxTries) =
callApi client "generate" [ tj blocks, tj maxTries]
generate client blocks maxTries =
callApi client "generate" args `catch` onFail
where
args = tj blocks : maybe [] (pure . tj) maxTries
onFail (HttpExceptionRequest _ (StatusCodeException rsp _))
| responseStatus rsp == status500
= getNewAddress client Nothing >>= flip (generateToAddress client blocks) maxTries
onFail e = throw e

-- | The generatetoaddress RPC mines blocks immediately to a specified address.
-- See https://bitcoin.org/en/developer-reference#generatetoaddress for more details.
@@ -189,8 +199,7 @@ instance FromJSON Transaction where
<*> o .: "sigops"
parseJSON _ = mzero

data CoinBaseAux = CoinBaseAux { cbFlags :: HexString
}
newtype CoinBaseAux = CoinBaseAux { cbFlags :: HexString }
deriving ( Show, Read, Ord, Eq )

instance FromJSON CoinBaseAux where
@@ -255,7 +264,7 @@ getBlockTemplate client = callApi client "getblocktemplate" []
-- the string "rejected" on failure.
--
-- We use 'StupidReturnValue' to parse this ridiculous API.
data StupidReturnValue = SRV { unStupid :: Bool }
newtype StupidReturnValue = SRV { unStupid :: Bool }

instance FromJSON StupidReturnValue where
parseJSON Null = return $ SRV True
Loading