haskoin-node
P2P library for Bitcoin and Bitcoin Cash
http://github.com/jprupp/haskoin-node#readme
| LTS Haskell 23.28: | 1.1.4 |
| Stackage Nightly 2026-11-08: | 2.3.1 |
| Latest on Hackage: | 2.3.1 |
haskoin-node-2.3.1@sha256:717cd15daa660737407c591e0d4b8169c72bba850ea9253adb5232403a004d71,2261Module documentation for 2.3.1
- Haskoin
Haskoin Node
Haskoin Node is a peer-to-peer networking library for Bitcoin (BTC) and Bitcoin Cash (BCH), written in Haskell. It connects to the network, keeps a pool of healthy peers, and syncs block headers into a RocksDB database.
It does not download or validate blocks and transactions by itself. It publishes everything that happens as events, and gives you the peers to ask for the data you need. It is the networking layer of Haskoin Store.
Contents
- Why Haskoin Node
- Design principles
- Features
- Installation
- Quick start
- Tutorial: a block watcher
- Concepts
- Usage guide
- Configuration
- Module overview
- Security notes
- Development
- Related projects
- License
Why Haskoin Node
A program that wants Bitcoin data has two usual options. It can run a full node such as Bitcoin Core next to it and talk to its RPC interface, which means operating a second large piece of software. Or it can speak the peer-to-peer protocol itself, which means solving the same problems every node solves: finding peers, keeping good ones, dropping bad ones, parsing untrusted messages safely, and following the header chain through reorganisations.
Haskoin Node solves those problems once, as a library. It gives a Haskell program a direct, well-behaved presence on the network, and stops there: what to download, what to validate and what to store is up to the program. It is the networking layer of Haskoin Store, which indexes the whole Bitcoin and Bitcoin Cash block chains this way without a full node.
Design principles
- Do one job. Keep connected and keep the header chain current. Blocks, transactions, validation and storage of anything but headers belong to the application, because every application wants something different.
- Headers are the source of truth. Headers are small (80 bytes) and carry the proof of work. With them, the node knows which chain is real without downloading blocks, and can tell the application which blocks to fetch.
- Tell, don’t ask. Everything the node learns becomes an event on a publisher. The application subscribes and reacts; the node never needs to know who is listening.
- Peers are strangers. Message sizes are checked before payloads are read, anything invalid ends the connection, relayed addresses are filtered, and a peer cannot push data faster than the node can handle it.
- Prefer good peers, but keep moving. Peers are ranked by measured latency so the fastest are used first, and every connection is eventually replaced so the node never depends on the same few peers forever.
- Small, isolated components. The peer manager, the header chain and each connection are separate NQE processes with their own state. One misbehaving peer dies alone.
Features
| Area | What you get |
|---|---|
| Networks | Every network of haskoin-core: Bitcoin and Bitcoin Cash mainnet, testnets and regtest |
| Peer discovery | DNS seeds and addresses relayed by peers, or a static list of peers |
| Peer management | Version handshake, ping-based latency, peers sorted by median ping, rotation after a maximum age |
| Header sync | Headers downloaded from one peer at a time, connected to the chain with the most work, stored in RocksDB |
| Events | Best header changes, sync completion, peer connections and every message received |
| Data requests | Fetch blocks and transactions from a peer, with a timeout |
| Protection | Strict parsing, per-command size limits, back-pressure, bounded address pool |
What is not included
- No block or transaction validation, and no mempool. Haskoin Store does this on top of the events.
- No inbound connections: the node only connects out.
- No compact blocks, Bloom filters (BIP-37) or compact block filters (BIP-157).
Installation
System libraries
Haskoin Node needs RocksDB and
libsecp256k1 0.2.0 or later, with
pkg-config to find them.
# Debian and Ubuntu
sudo apt-get install librocksdb-dev libsecp256k1-dev pkg-config
# Fedora
sudo dnf install rocksdb-devel libsecp256k1-devel pkgconf
# macOS with Homebrew
brew install rocksdb secp256k1 pkg-config
# Nix
nix-shell -p rocksdb secp256k1 pkg-config
Some older distributions ship a libsecp256k1 below 0.2.0. See the haskoin-core installation notes for how to build it.
Check the libraries are found
pkg-config --modversion libsecp256k1 # 0.2.0 or later
ls /usr/include/rocksdb/c.h # or $(brew --prefix)/include/rocksdb/c.h
Compiler
It needs GHC 9.2 or later, because it uses OverloadedRecordDot. It is built
and tested with the GHC of the Stackage nightly in stack.yaml.
With Cabal
build-depends:
base
, data-default
, haskoin-core
, haskoin-node
, nqe
, rocksdb-haskell-jprupp
You open the database with rocksdb-haskell-jprupp and create the event
publisher with nqe.
With Stack
Recent Stackage nightly snapshots include Haskoin Node. With an older resolver,
add it and its dependencies to stack.yaml:
extra-deps:
- haskoin-node-2.3.1
- haskoin-core-1.6.1
- secp256k1-haskell-2.0.0
- base16-2.0
- rocksdb-haskell-jprupp-2.6.1
- rocksdb-query-0.6.1
- nqe-0.6.9
Step by step with Stack
-
Install Stack and the libraries above.
-
Create a project:
stack new node-demo simple cd node-demo -
Add the packages listed under With Cabal to
build-dependsinnode-demo.cabal, plusnetwork. -
If your resolver is older than the packages, add the
extra-depsshown under With Stack tostack.yaml. -
Put the quick start program in
src/Main.hsand run it:stack runWithin a few seconds it logs connections and starts printing header heights. A full header sync of Bitcoin usually takes minutes and on the order of a hundred megabytes of disk; it resumes where it stopped if you interrupt it.
Quick start
This program connects to Bitcoin, syncs headers, and prints what happens:
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedRecordDot #-}
import Control.Monad (forever)
import Data.Default (def)
import Database.RocksDB (Config (..), withDB)
import Haskoin (NetworkAddress (..), btc, sockToHostAddress)
import Haskoin.Node
import NQE (receive, withPublisher, withSubscription)
import Network.Socket (SockAddr (..))
main :: IO ()
main =
withLogger LevelInfo $ \logger ->
withDB "/tmp/haskoin-node" def {createIfMissing = True} $ \db ->
withPublisher $ \pub ->
withSubscription pub $ \events -> do
let cfg =
NodeConfig
{ maxPeers = 8,
db = db,
cf = Nothing,
peers = [],
discover = True,
address = NetworkAddress 0 (sockToHostAddress (SockAddrInet 0 0)),
net = btc,
pub = pub,
timeout = 120,
maxPeerLife = 48 * 3600,
connect = withConnection,
logger = logger
}
withNode cfg $ \_node -> forever $
receive events >>= \case
ChainEvent (ChainBestBlock bn) ->
putStrLn ("Best header: " <> show bn.height)
ChainEvent (ChainSynced _) ->
putStrLn "Headers in sync"
PeerEvent (PeerConnected p) ->
putStrLn ("Connected: " <> show p)
_ -> return ()
Subscribe to the publisher before calling withNode, as here, or you may miss
the first events.
Tutorial: a block watcher
This builds a program that prints every new Bitcoin block with its number of transactions. It shows the intended division of labour: the node follows headers and tells you about them, and you fetch what you need.
1. Wait until the headers are synced
At start-up the node downloads hundreds of thousands of headers, each one a
ChainBestBlock event. Reacting to each of those would mean fetching every
historical block. Wait for ChainSynced first:
waitSynced :: Inbox NodeEvent -> IO ()
waitSynced events =
receive events >>= \case
ChainEvent (ChainSynced _) -> return ()
_ -> waitSynced events
2. React to new best headers
After that, each ChainBestBlock is a new block at the tip, or the new tip
after a reorganisation:
watch :: Network -> Node -> Inbox NodeEvent -> IO ()
watch net node events = forever $
receive events >>= \case
ChainEvent (ChainBestBlock bn) -> fetch net node bn
_ -> return ()
3. Fetch the block from the fastest peer
getPeers lists online peers, fastest first. Ask one, and try the next if it
fails or times out:
fetch :: Network -> Node -> BlockNode -> IO ()
fetch net node bn = getPeers node.peerMgr >>= go
where
hash = headerHash bn.header
go [] = putStrLn ("No peer could send block " <> show bn.height)
go (op : ops) =
getBlocks net 30 op.mailbox [hash] >>= \case
Just [b] ->
putStrLn (show bn.height <> ": " <> show (length b.txs) <> " transactions")
_ -> go ops
4. Put it together
Use the configuration from the quick start, and run the watcher
inside withNode:
withNode cfg $ \node -> do
waitSynced events
watch btc node events
What the node did for you
While this runs, the node keeps eight connections, measures and ranks them, drops silent or misbehaving peers and finds replacements, stores headers so a restart is quick, and switches to a heavier chain if one appears. The watcher is only twenty lines because none of that is its concern.
Concepts
Components
withNode starts two processes, built with NQE:
- The peer manager (
Haskoin.Node.PeerMgr) finds peer addresses, connects to them, does the version handshake, pings them, and drops those that are slow, silent, misbehaving or too old. - The chain (
Haskoin.Node.Chain) asks one peer at a time for headers, connects them to the headers it has, follows the chain with the most work, and stores the headers in RocksDB.
Each peer connection is its own process (Haskoin.Node.Peer), run by a
supervisor inside the peer manager.
Events
Everything is published to the Publisher NodeEvent in the configuration:
| Event | When |
|---|---|
ChainEvent (ChainBestBlock node) |
The best header changed, including on start |
ChainEvent (ChainSynced node) |
Headers caught up with the network (once) |
PeerEvent (PeerConnected peer) |
A peer finished the handshake |
PeerEvent (PeerDisconnected peer) |
An online peer went away |
PeerEvent (PeerMessage peer msg) |
A peer sent a message: MInv, MBlock, MTx and so on |
“In sync” means the best header is less than two hours old, has at least the minimum chain work of the network, and no peer is left to sync from.
Back-pressure
A peer may have at most 16 messages published and not yet handled by the node. Past that, the node stops reading its socket, so a fast peer fills its own TCP window instead of the node’s memory. Your subscriber should keep reading events; a subscription that falls far behind holds memory.
Database layout
Headers are stored in the column family you configure, or the default one:
| Key prefix | Value |
|---|---|
0x90 |
header (BlockNode) by hash |
0x91 |
best header |
0x92 |
data version |
You can keep your own data in the same database, as Haskoin Store does, as long as your keys do not start with these bytes.
Usage guide
Picking a peer and requesting data
ps <- getPeers node.peerMgr -- online peers, fastest first
case ps of
op : _ -> do
let p = op.mailbox
mblocks <- getBlocks btc 30 p [blockHash] -- Maybe [Block]
mtxs <- getTxs btc 30 p [txHash] -- Maybe [Tx]
sendMessage MMempool p
[] -> return ()
getBlocks, getTxs and getData return Nothing if the peer does not send
everything, in order, before the timeout in seconds. pingPeer measures a round
trip.
Querying headers
best <- chainGetBest node.chain
mnode <- chainGetBlock node.chain someHash
isMain <- chainBlockMain node.chain someHash
fork <- chainGetSplitBlock node.chain nodeA nodeB
parents <- chainGetParents node.chain height top
synced <- chainIsSynced node.chain
runChainT runs the header functions of haskoin-core, such as getAncestor,
against the database of the chain.
Static peers
cfg {peers = ["node1.example.com", "10.0.0.5:8333", "[2001:db8::1]:8333"], discover = False}
A peer without a port uses the default port of the network.
Custom connections
connect decides how to open a connection. withConnection opens a plain TCP
socket. Replace it to go through a proxy, or to plug in mock peers in tests, as
the test suite does.
Logging
withLogger level logs to standard error, one line per message, such as
[Info#Chain] Best block header at height 870000. Build a Logger with your
own push function to log elsewhere.
Configuration
| Field | Meaning |
|---|---|
maxPeers |
Maximum number of peers to connect to |
db |
RocksDB handle for the headers |
cf |
Column family for the headers, or Nothing for the default one |
peers |
Static peers, as host, host:port or [ipv6]:port |
discover |
Use DNS seeds and addresses relayed by peers |
address |
This node’s address, sent in version messages |
net |
Network constants from haskoin-core (btc, bch, btcTest, …) |
pub |
Publisher that receives every NodeEvent |
timeout |
Seconds of silence, or without a pong, before a peer is dropped |
maxPeerLife |
Seconds after which a peer is dropped, so that connections rotate |
connect |
How to open a connection; usually withConnection |
logger |
Where to log; see withLogger |
Module overview
Haskoin.Node is the only exposed module. It re-exports:
| Part | Contents |
|---|---|
| Node | NodeConfig, NodeEvent, Node, withNode, withConnection |
| Peers | Peer, PeerEvent, sendMessage, getBlocks, getTxs, getData, pingPeer, killPeer |
| Peer manager | PeerMgr, OnlinePeer, getPeers, getOnlinePeer, toSockAddr, isRoutable |
| Chain | Chain, ChainEvent, chainGetBest, chainGetBlock, chainGetAncestor, chainGetParents, chainGetSplitBlock, chainBlockMain, chainIsSynced, runChainT |
| Logging | Logger, LogLevel, withLogger, withSource, logDebug … logError |
The lower-level functions that feed messages to the peer manager and the chain are exported too, for programs that wire the components themselves.
Security notes
- Every message header is checked before its payload is read. The payload limit
is the
maxPayloadSizeof the command on the network: on Bitcoin Cash, 2 MiB for everything but block messages. - List messages are refused as soon as their count is over the limit, such as 2000 headers, 1000 addresses or 50000 inventory entries.
- A peer that sends anything invalid is disconnected.
- Addresses relayed by peers are only used if they are public unicast addresses, so a peer cannot make the node connect to services on its own host or network. Static peers are not checked.
- At most 4096 relayed addresses are kept.
- Headers are not reported as synced until they have the minimum chain work of the network. Above that work, forks from far below the tip on a chain with less work are refused.
- The node trusts the chain with the most work. It does not validate blocks: check the data you get from peers before relying on it.
Development
git clone https://github.com/jprupp/haskoin-node.git
cd haskoin-node
stack build # build the library
stack test # run the tests
stack haddock --no-haddock-deps # build the API documentation
On NixOS, or with stack --nix, the nix section of stack.yaml provides
RocksDB and libsecp256k1.
package.yaml is the source of the package description. Change it rather than
haskoin-node.cabal, which hpack generates.
The tests are in test/ and use hspec. They run
against mock peers on the Bitcoin Cash regression test network, so they need no
Internet access.
Contributing
Pull requests are welcome.
- Format the code with Ormolu.
- Add tests for the behaviour you change.
- Describe the change under a new version in
CHANGELOG.md. The file follows Keep a Changelog, and versions follow Semantic Versioning.
Related projects
- haskoin-core has the Bitcoin data types and protocol that this library speaks.
- haskoin-store indexes blocks and transactions on top of this node and serves them over a REST API.
- nqe provides the processes, supervisors and publishers.
- rocksdb-query stores the headers.
License
Haskoin Node is released under the MIT License.
Changes
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
[2.3.1] - 2026-11-07
Changed
- Documentation: the README explains the purpose and design of the node, with installation steps, configuration, security notes and a tutorial, and the Haddock of every module and function says why it works the way it does.
- Build against nqe 0.6.9, rocksdb-haskell-jprupp 2.6.1, rocksdb-query 0.6.1 and Stackage nightly-2026-11-07.
[2.3.0] - 2026-11-06
Changed
- This package requires haskoin-core 1.6.0, the release with the fixes of the November 2026 security review.
- Breaking: the
version,timestampandstartHeightfields of theVersionof anOnlinePeerare signed numbers, as haskoin-core 1.6.0 reads them.buildVersiontakes the same arguments as before. - The headers are not reported as synced before the best header has the
minimumChainWorkof the network. This holds for theChainSyncedevent and forchainIsSynced. A recent header on a chain with less work used to be enough. - Once the best header has the
minimumChainWorkof the network, a peer whose headers fork from far below the tip, on a chain with less work, is disconnected. haskoin-core 1.6.0 refuses such headers. - A peer that sends a header the node already has at or below a checkpoint is no longer disconnected. haskoin-core 1.6.0 returns the stored header.
- Transactions from Bitcoin Cash peers are read in the format without witness only, as haskoin-core 1.6.0 reads them on a network without SegWit.
- The log line for an invalid payload gives the reason the parser refused it.
- The payload size limit is the
maxPayloadSizeof the command on the network instead of the network’smaxMessageSize. On Bitcoin Cash that is 2 MiB for every message butblock,cmpctblockandblocktxn, which may be twice the block size.
Fixed
- Peers that send more than 50000 entries in an
invorgetdatamessage, or a block locator of more than 101 hashes, are disconnected. haskoin-core 1.6.0 refuses such a message as soon as it reads the count.
[2.2.0] - 2026-11-04
Changed
- Breaking:
Peerhas apendingfield,wrapPeertakes itsTVar Int, andpeertakes thePeerthatwrapPeerbuilt instead of the busyTVar. - Messages from a peer apply backpressure. A peer may have at most
maxPendingMessagesmessages waiting for the node; after that the node stops reading its socket until it catches up. Address, header, version, verack, ping and pong messages are handled to completion before the next one is taken. A fast peer could fill the node’s unbounded queues before. - Outgoing messages are logged by command at debug level, not in full.
Fixed
- Bitcoin Cash headers sync again. This package now requires haskoin-core
1.5.1, which evaluates the ASERT difficulty rule at the parent block. With
haskoin-core 1.5.0 the node stopped at mainnet block 975899 with
Incorrect difficulty bits, because that release checked the bits of each header with a formula that used the header’s own timestamp. - Network magic and payload size are checked right after the message header,
before the payload is read. The size limit is the network’s
maxMessageSizeinstead of a fixed 32 MiB. An oversized message used to be logged and its payload then parsed as the next header. - Peers that send more than 2000 headers or more than 1000 addresses in one message are disconnected before the message is decoded.
- Address and header messages from a peer are ignored until it completes the handshake.
- A second version or verack from a peer disconnects it. Each one used to announce the peer as connected again.
- Relayed addresses that are not public unicast addresses (loopback,
private, link-local, multicast, documentation and similar ranges, or port
0) are not added to the address pool.
isRoutableis exported. - A peer that does not answer a ping within the timeout is disconnected, even if it keeps sending other messages.
- Only headers from the syncing peer reset its sync timeout. Another peer’s headers could keep a silent syncing peer from ever timing out.
- The peer manager rechecks
maxPeerswhen it handles a queued connection, so the connect loop can no longer go over the limit while the manager is busy. - Purging an old chain database with a column family deleted the same keys from the default column family too. The purge now deletes keys as it walks them instead of building a list of all of them in memory.
[2.1.2] - 2026-11-04
Fixed
- An empty headers message from the syncing peer ends the header sync. The node used to take it as a reason to ask the same peer again, and kept sending getheaders in a tight loop, thousands per second, whenever its best header was the peer’s tip after a full batch of 2000.
[2.1.1] - 2026-11-04
Changed
- The loop that parses messages from a peer uses
loopForevertoo, like every other long-running loop. - Tests use IPv4 only: the mock peer is at
127.0.0.1instead of[::1], and the address property test generates IPv4 addresses. On a host without IPv6 the mock peer could not be resolved and the peer and chain tests hung.
[2.1.0] - 2026-11-03
- Update to haskoin-core-1.5.0.
[2.0.0] - 2026-10-31
Changed
- Replace monad-logger with fast-logger. Configuration records take a
Logger, and functions need onlyMonadIOorMonadUnliftIO. - Require haskoin-core 1.5.0, whose
buildMerkleRootreturnsEither String MerkleRoot.
[1.4.4] - 2026-08-31
Added
- Log
connectBlockserror message.
Changed
- Peer connection logged incorrectly as warn is now logged as info.
Fixed
- Correct documentation for
importHeadersfunction.
[1.4.3] - 2026-08-13
Fixed
- Fix regression with peer disconnection.
[1.4.2] - 2026-08-13
Fixed
- Fix regression with peer selection.
[1.4.1] - 2026-08-13
Removed
- Remove PeerException type which is no longer used.
[1.4.0] - 2026-08-13
Changed
- Add monad transformers and monad-logger again because logging is too slow.
[1.3.1] - 2026-08-12
Added
- Add monad transformers to support haskoin-store.
[1.3.0] - 2026-08-12
Changed
- Simplify modules to make compatible with upstream changes.
[1.2.0] - 2026-08-12
Changed
- Upstream changes on multiple libraries.
[1.1.4] - 2025-05-08
Changed
- Move to personal repository.
[1.1.3] - 2024-05-23
Fixed
- Tickle a peer whenever a message is received.
[1.1.2] - 2024-05-23
Fixed
- Correct log messages from peer manager.
[1.1.1] - 2024-05-23
Fixed
- Peers timeout more aggressively.
[1.1.0] - 2024-03-14
Changed
- Update LTS Haskell & upstream dependencies.
[1.0.1] - 2023-08-03
Changed
- Add compatibility with latest LTS Haskell.
[1.0.0] - 2023-07-28
Changed
- Make compatible with latest haskoin-core.
- Use DuplicateRecordFields and OverloadedRecordDot.
- Simplify pub/sub queues.
- Multiple refactoring passes.
[0.18.1] - 2022-07-27
Fixed
- Set default port for peers where it is unset.
[0.18.0] - 2022-07-27
Added
- Support setting up and connecting to IPv6 peers.
[0.17.14] - 2021-08-14
Fixed
- Reduce verbosity on incoming header decode test.
- Show appropriate error message upon receiving empty headers.
[0.17.13] - 2021-08-14
Added
- Display more details about invalid incoming headers.
[0.17.12] - 2021-05-17
Fixed
- Do not connect to more than the maximum number of peers.
[0.17.11] - 2021-05-17
Added
- Display message command that disconnects a peer.
[0.17.10] - 2021-05-17
Fixed
- Correct disconnect timeout algorithm bug.
[0.17.9] - 2021-05-17
Fixed
- Add randomised timeouts to avoid disconnecting all peers.
[0.17.2] - 2021-03-09
Fixed
- Do not start chain actor until database initialized.
[0.17.1] - 2021-01-08
Changed
- Depend on haskoin-core-0.17.3.
[0.17.0] - 2020-10-21
Added
- Support for Bitcoin Cash November 2020 hard fork.
- BlockHeaders instance for ReaderT Chain.
[0.16.0] - 2020-07-23
Changed
- Add support for column families.
[0.15.0] - 2020-07-20
Changed
- Use new Haskell bindings for RocksDB.
[0.14.1] - 2020-06-19
Fixed
- Correct flawed peer locking logic in Chain actor.
[0.14.0] - 2020-06-18
Changed
- Massively refactor everything in a non-backwards-compatible way.
- Use MIT license.
- Bump haskoin-core.
- Bump secp256k1-haskell.
Fixed
- Fix getting stuck on a single peer.
[0.13.0] - 2020-05-08
Changed
- Depend on Haskoin Store 0.13.3.
- Better code organisation.
[0.12.0] - 2020-05-06
Changed
- Add a test suite that simulates network instead of connecting to real one.
[0.11.3] - 2020-05-03
Changed
- Revert including multiline decoding error text in logs.
[0.11.2] - 2020-05-03
Changed
- Include header decoding error text in logs.
[0.11.1] - 2020-05-03
Changed
- Improve logging.
[0.11.0] - 2020-05-03
Changed
- Set peer too old time
[0.10.1] - 2020-05-03
Changed
- Disconnect old peers after 48 hours instead of 30 minutes.
[0.10.0] - 2020-05-03
Changed
- Move modules out of Network.Haskoin namespace.
- Add better and more logging.
- Change Manager module name and related values to PeerManager.
[0.9.21] - 2020-04-07
Removed
- Remove unnecessary logging.
[0.9.20] - 2020-04-07
Changed
- Better log messages.
- Less verbose debug logging.
[0.9.19] - 2020-04-07
Changed
- Better log messages.
[0.9.18] - 2020-04-07
Added
- More aggressive peer discovery.
[0.9.17] - 2020-04-07
Added
- Peers are disconnected automatically after awhile.
[0.9.16] - 2020-02-08
Added
- Lower bound versions for some dependencies.
[0.9.15] - 2020-01-15
Changed
- Update to support new
NetworkAddressdata structure fromhaskoin-core.
[0.9.14] - 2019-12-10
Removed
- No longer support storing peers in db as performance tradeoff doesn’t justify it.
[0.9.13] - 2019-10-08
Changed
- Really store peers in db.
[0.9.12] - 2019-10-08
Changed
- Demote some logging to debug level.
[0.9.11] - 2019-10-02
Added
- Add
-O2optimisations to GHC.
[0.9.10] - 2019-04-19
Added
- Increase debugging information where application freezes.
[0.9.9] - 2019-04-12
Added
- Increase debugging information.
[0.9.8] - 2019-04-12
Changed
- Increase version of haskoin-core to 0.9.0.
- Fix some tests.
[0.9.7] - 2019-04-12
Added
- More debugging.
Changed
- Be defensive against duplicate peers.
- Increase interval between housekeeping pings.
- Replace peers in database atomically.
[0.9.6] - 2019-04-01
Changed
- Randomize known peers instead of keeping scores.
- Simplify peer management code to avoid freezes.
- Merge logic for chain and manager.
[0.9.5] - 2018-11-14
Changed
- Do not record new peers in database when peer discovery is disabled.
[0.9.4] - 2018-11-01
Changed
- Don’t spam best block events.
[0.9.3] - 2018-10-22
Changed
- Correct display of milliseconds in log.
- Correct bug when receiving headers from unknown peer.
- Simplify chain syncing code.
[0.9.2] - 2018-10-18
Changed
- Peer dies immediately when receiving a bad message.
[0.9.1] - 2018-10-18
Changed
- Keep track of last synced header from a peer to avoid endless loops on large reorgs.
[0.9.0] - 2018-10-17
Changed
- Use an STM listener instead of a publisher for the node API.
[0.8.2] - 2018-10-17
Added
- Expose
ChainMessageandManagerMessagetypes fromHaskoin.Nodemodule.
[0.8.1] - 2018-10-11
Changed
- Corrected documentation for
killPeerfunction. - Leave time out of logic code.
[0.8.0] - 2018-10-09
Changed
- Peers are now killed directly instead of through peer manager.
Removed
- Chain no longer needs peer manager.
[0.7.2] - 2018-10-09
Added
- Compatibility with base 4.12.
Changed
- Update base to 4.9.
[0.7.1] - 2018-10-09
Added
- Allow to easily obtain a peer’s publisher.
[0.7.0] - 2018-10-09
Added
- Versioning for chain and peer database.
- Automatic purging of chain and peer database when version changes.
- Add extra timers.
- Add publishers to every peer.
Changed
- Full reimplementation of node API.
- Simplify peer selection and management.
- Merge manager and peer events.
- Rename configuration variables for node.
- Separate logic from actors for peer manager and chain.
Removed
- Remove irrelevant fields from peer information.
- Remove unreliable peer block head tracking.
- Remove dependency on deprecated binary conduits.
- Remove Bloom filter support from manager.
- Remove unreliable peer request tracking code.
- Remove separate manager events.
[0.6.1] - 2018-09-14
Changed
- Fix bug where peer height did not update in certain cases.
[0.6.0] - 2018-09-14
Added
- Documentation everywhere.
Changed
- Make compatible with NQE 0.5.
- Use supervisor only in peer manager.
- API quality of life changes.
- Exposed module is now only
Haskoin.Node.
Removed
- No more direct access to internals.
[0.5.2] - 2018-09-10
Changed
- Improve dependency definitions.
[0.5.1] - 2018-09-10
Changed
- Dependency
sec256k1changes tosecp256k1-haskell.
[0.5.0] - 2018-09-09
Added
- New
CHANGELOG.mdfile. - Use
nqefor concurrency. - Peer discovery.
- RocksDB peer and block header storage.
- Support for Merkle blocks.
Changed
- Split out of former
haskoinrepository. - Use hpack and
package.yaml. - Old
haskoin-nodepackage now renamed toold-haskoin-nodeand deprecated.
Removed
- Removed Old Haskoin Node package completely.
- Removed Stylish Haskell configuration file.
- Remvoed
haskoin-coreandhaskoin-walletpackages from this repository.