Commit graph

154 commits

Author SHA1 Message Date
Dave Collins
4328461f36 Update for recent btcchain and btcnet API changes. 2014-05-27 10:12:59 -05:00
Josh Rickmar
bcc78565fd Initial pass at updating to btcnet.
This change modifies the params struct to embed a *btcnet.Params,
removing the old parameter fields that are handled by the btcnet
package.

Hardcoded network checks have also been removed in favor of modifying
behavior based on the current active net's parameters.

Not all library packages, notable btcutil and btcchain, have been
updated to use btcnet yet, but with this change, each package can be
updated one at a time since the active net's btcnet.Params are
available at each callsite.

ok @davecgh
2014-05-23 01:02:14 -05:00
Dave Collins
0a7543516c Update block manager chainstate for all sources.
This commit updates the block manager's local chain state when a block
processed by submitting it directly to the block manager as opposed to
only when it comes from the network.

Also, it modifies the submitblock RPC to use the concurrent safe block
manager process block instead of the unsafe btcchain version.

The combination of these two fixes ensure the internal block manager chain
state is properly synced with the actual btcchain state regardless of how
blocks are added.
2014-05-02 23:02:10 -05:00
Dave Collins
92ca0e92c0 Implement getwork RPC.
This commit adds full support for the getwork RPC which can be used to
support external mining through applications such as cgminer.

Closes #125.
2014-05-01 10:52:28 -05:00
David Hill
8a322e4792 Bypass rate limiter for sendrawtransaction.
ok @davecgh
2014-04-23 07:45:56 -04:00
mydesktop
ab002c90cc Implement a rebroadcast handler.
This commit implements a rebroadcast handler which deals with
rebroadcasting inventory at a random time interval between 0 and 30
minutes.  It then uses the new rebroadcast logic to ensure transactions
which were submitted via the sendrawtransaction RPC are rebroadcast until
they make it into a block.

Closes #99.
2014-03-27 14:09:33 -05:00
Dave Collins
e98db34ef2 Add infrastructure for creating a block template.
This commit adds a new function named NewBlockTemplate along with
supporting infrastructure which is part of the core functionality needed
to support mining.

In particular the function creates a new block template which contains a
fully populated block with a zero nonce that is ready to be solved as well
as additional information regarding the fees and number of signature
operations for each transaction included in the block.  The specific
transaction selection logic mirrors the reference implementation.

Various cleanup, optimizations, and comment suggestions provided by
@owainga.  Also contains some naming suggestions and comment fixes from
@flammit.
2014-03-22 11:47:38 -05:00
Dave Collins
f1a4dfb86d Update chain state with best block.
Rather than updating the new chain state with the hash and height of the
block that was just processed, query the database for the best block.
This is needed because the block that was just processed might be a side
chain block or have caused a reorg.
2014-03-20 14:08:46 -05:00
Dave Collins
1d674905e0 Introduce a chain state to block manager.
This commit introduces a chain state that is updated as blocks are
processed into the block chain instance associated with the block manager.

This has been done because btcchain is currently not safe for concurrent
access and the block manager is typically quite busy processing block and
inventory.  This approach allows fast access to most chain information in
a concurrent safe fashion.
2014-03-20 01:06:59 -05:00
David Hill
ebf5a3e850 add peer to block and tx rejection debug messages.
ok @davecgh
2014-03-17 22:52:55 -04:00
Dave Collins
7a885b3cf6 Reject orphan transactions from sendrawtransaction.
This commit modifies the sendrawtransaction RPC to reject transactions
which are orphans.  This mirrors the behavior of the reference
implementation.
2014-03-17 17:32:30 -05:00
Dave Collins
510a44bdd9 Fix some comment typos. 2014-03-13 08:45:41 -05:00
Dave Collins
b661dd3693 Convert block manager block handler to pure FIFO.
Rather than having a separate query channel for the block manager, use the
same channel so the block handler acts as a pure FIFO queue.  This
prevents possible starvation of query related messages.

ok @owainga
2014-03-12 13:26:06 -05:00
Josh Rickmar
a7d5b365b1 Retain order when processing client notifications.
This change modifies the RPC server's notifiation manager from a
struct with requests, protected by a mutux, to two goroutines.  The
first maintains a queue of all notifications and control requests
(registering/unregistering notifications), while the second reads from
the queue and processes notifications and requests one at a time.

Previously, to prevent slowing down block and mempool processing, each
notification would be handled by spawning a new goroutine.  This lead
to cases where notifications would end up being sent to clients in a
different order than they were created.  Adding a queue keeps the
order of notifications originating from the same goroutine, while also
not slowing down processing while waiting for notifications to be
processed and sent.

ok @davecgh
2014-03-04 11:15:25 -05:00
Dave Collins
54203d7db0 Rework and improve websocket notification system.
This commit refactors the entire websocket client code to resolve several
issues with the previous implementation.  Note that this commit does not
change the public API for websockets.  It only consists of internal
improvements.

The following is the major issues which have been addressed:
- A slow websocket client could impede notifications to all clients
- Long-running operations such as rescans would block all other requests
  until it had completed
- The above two points taken together could lead to apparant hangs since
  the client doing the rescan would eventually run out of channel buffer
  and block the entire group of clients until the rescan completed
- Disconnecting a websocket during certain operations could lead to a hang
- Stopping the rpc server with operations under way could lead to a hang
- There were no limits to the number of websocket clients that could
  connect

The following is a summary of the major changes:

- The websocket code has been split into two entities: a
  connection/notification manager and a websocket client
- The new connection/notification manager acts as the entry point from
  the rest of the subsystems to feed data which potentially needs to
  notify clients
- Each websocket client now has its own instance of the new websocket
  client type which controls its own lifecycle
- The data flow has been completely redesigned to closely resemble the
  peer data flow
- Each websocket now has its own long-lived goroutines for input, output,
  and queuing of notifications
- Notifications use the new notification queue goroutine along with
  queueing to ensure they dont't block on stalled or slow peers
- There is a new infrastructure for asynchronously executing long-running
  commands such as a rescan while still allowing the faster operations to
  continue to be serviced by the same client
- Since long-running operations now run asynchronously, they have been
  limited to one at a time
- Added a limit of 10 websocket clients.  This is hard coded for now, but
  will be made configurable in the future

Taken together these changes make the code far easier to reason about and
update as well solve the aforementioned issues.

Further optimizations to improve performance are possible in regards to
the way the connection/notification manager works, however this commit
already contains a ton of changes, so they are being left for another
time.
2014-02-19 00:53:05 -06:00
Francis Lam
b89e93e52f Added notifyallnewtxs custom websocket command
Changed mempool.MaybeAcceptTransaction to accept an additional parameter
to differentiate betwee new transactions and those added from
disconnected blocks.

Added new fields to requestContexts to indicate which clients want to
receive all new transaction notifications.

Added NotifyForNewTx to rpcServer to deliver approriate transaction
notification.
2014-02-08 17:15:17 -05:00
Dave Collins
238d942a69 Make go vet happy. 2014-02-04 15:34:44 -06:00
Dave Collins
cdbe387545 Add warning on invalid msg type in block manager. 2014-02-04 09:47:12 -06:00
Dave Collins
d949072d6d Change new get sync peer bits to a query channel.
Rather than using a dedicated channel for the sync peer request and reply,
use a single query channel that accepts a query type as well as a reply
channel.  This will allow other queries to be added in the future without
the various queries being racy.
2014-02-04 09:47:07 -06:00
Dave Collins
ba5e457c38 Finish getpeerinfo RPC syncnode field.
This commit adds code to get the current sync peer from the block manager
for use in the getpeerinfo RPC.
2014-02-04 00:27:10 -06:00
Dave Collins
5ec951f6a7 Rework and improve headers-first mode.
This commit improves how the headers-first mode works in several ways.

The previous headers-first code was an initial implementation that did not
have all of the bells and whistles and a few less than ideal
characteristics.  This commit improves the heaers-first code to resolve
the issues discussed next.

- The previous code only used headers-first mode when starting out from
  block height 0 rather than allowing it to work starting at any height
  before the final checkpoint.  This means if you stopped the chain
  download at any point before the final checkpoint and restarted, it
  would not resume and you therefore would not have the benefit of the
  faster processing offered by headers-first mode.
- Previously all headers (even those after the final checkpoint) were
  downloaded and only the final checkpoint was verified.  This resulted in
  the following issues:
  - As the block chain grew, increasingly larger numbers of headers were
    downloaded and kept in memory
  - If the node the node serving up the headers was serving an invalid
    chain, it wouldn't be detected until downloading a large number of
    headers
  - When an invalid checkpoint was detected, no action was taken to
    recover which meant the chain download would essentially be stalled
- The headers were kept in memory even though they didn't need to be as
  merely keeping track of the hashes and heights is enough to provde they
  properly link together and checkpoints match
- There was no logging when headers were being downloaded so it could
  appear like nothing was happening
- Duplicate requests for the same headers weren't being filtered which
  meant is was possible to inadvertently download the same headers twice
  only to throw them away.

This commit resolves these issues with the following changes:

- The current height is now examined at startup and prior each sync peer
  selection to allow it to resume headers-first mode starting from the
  known height to the next checkpoint
- All checkpoints are now verified and the headers are only downloaded
  from the current known block height up to the next checkpoint.  This has
  several desirable properties:
  - The amount of memory required is bounded by the maximum distance
    between to checkpoints rather than the entire length of the chain
  - A node serving up an invalid chain is detected very quickly and with
    little work
  - When an invalid checkpoint is detected, the headers are simply
    discarded and the peer is disconnected for serving an invalid chain
  - When the sync peer disconnets, all current headers are thrown away
    and, due to the new aforementioned resume code, when a new sync peer
    is selected, headers-first mode will continue from the last known good
    block
- In addition to reduced memory usage from only keeping information about
  headers between two checkpoints, the only information now kept in memory
  about the headers is the hash and height rather than the entire header
- There is now logging information about what is happening with headers
- Duplicate header requests are now filtered
2014-02-01 16:33:00 -06:00
Dave Collins
c6d865f3b5 Cleanup and slightly optimize the progress logging.
Previously the logging function which reports on progress was called for
every block, regardless of whether it was an orphan or not.  This could be
confusing since it could show a different number of blocks processed as
compared to the old versus new heights reported (orphans do not add to the
block height since they aren't extending the main chain).  Further, the
database had to be consulted for the latest block since the block we just
processed might not be the latest one if it was an orphan.  This is quite
a bit more time conusming than it should've been for progress reporting.

This commit modifies that to only include non-orphan blocks.  As a result,
the latest height shown will match the number of blocks processed (even
when there are orphans) and the additional block lookup from the database
is avoided.
2014-01-30 12:40:37 -06:00
Owain G. Ainsworth
042d9206a1 change some more code over to using newer btcdb apis. 2014-01-29 18:31:33 +00:00
Dave Collins
970c0cdb30 Misc cleanup.
This commit contains various code cleanup such as comment fixes and
function ordering consistency.
2014-01-28 18:57:07 -06:00
Dave Collins
f12ca20372 Enable memdb support.
This commit adds the btcdb memdb backend as a supported database type.
Note that users will NOT want to run in this mode because, being memory
only, it obviously does not persist the database when shutdown.

It is being added for testing purposes to help prevent constant abuse to
developer's hard drive when churning the block database multiple times a
day.
2014-01-19 20:44:06 -06:00
Dave Collins
33bb455365 Update for recent btcwire API changes. 2014-01-18 21:15:09 -06:00
Dave Collins
c99a227df2 Fix a couple of comment typos. 2014-01-10 22:32:05 -06:00
Josh Rickmar
035f8f82b7 Switch to btcutil for certificate generation. 2014-01-10 15:41:57 -05:00
Dale Rahn
a5cc3196b4 Clear fetchheaders fields if in that mode and syncpeer detaches. 2014-01-09 13:22:42 -05:00
Dave Collins
b3f63cf35e Fix typo in fetch blocks log message. 2014-01-09 12:13:14 -06:00
Dave Collins
3946d84887 Make use of the new size hint functions in btcwire.
This commit changes a couple of sections which deal with large lists of
inventory vectors to use the new size hint functions recently added to
btcwire.  This allows a bit more efficiency since the size of the list is
known up front and we can therefore avoid dynamically growing the backing
array several times.  This also helps avoid a Go bug that leaks memory on
appends and GC churn.
2014-01-08 17:46:59 -06:00
Dave Collins
34657d43d9 Add the useragent to the new valid peer message.
This commit modifies the new valid peer message to display the useragent.
Previously this information was only available by setting the PEER
subsystem debuglevel to debug or lower.

This was prompted by #64.
2014-01-07 11:16:15 -06:00
Dave Collins
aeec39c1ff Add 2014 to copyright dates. 2014-01-01 10:16:15 -06:00
Dave Collins
17a9b41bef Cleanup peer.go.
This commit does some housekeeping on peer.go to make the code more
consistent, correct a few comments, and add new comments to explain the
peer data flow.  A couple of examples are variables not using the standard
Go style (camelCase) and comments that don't match the style of other
comments.
2013-12-24 14:05:28 -06:00
Dave Collins
cc9aadf041 Don't use headers first when checkpoints disabled.
Headers first relies on having valid checkpoints, so if checkpoints are
disabled, it needs to be disabled as well.
2013-12-20 14:01:25 -06:00
Dave Collins
011025dc0d Fix regtest mode with new headers-first approach.
The regression test does not work properly with the new headers-first
download approach, so force the old inv-based block download for
regression test mode.
2013-12-12 18:10:06 -06:00
Dale Rahn
7b406dcb0f Implement a fast path for the Initial Block Download.
It is not necessary to do all of the transaction validation on
blocks if they have been confirmed to be in the block chain leading
up to the final checkpoint in a given blockschain.

This algorithm fetches block headers from the peer, then once it has
established the full blockchain connection, it requests blocks.
Any blocks before the final checkpoint pass true for fastAdd on
btcchain operation, which causes it to do less valiation on the block.
2013-12-12 17:24:05 -05:00
Dave Collins
eb8688df79 Convert btcd to use new btclog package.
Also, make every subsystem within btcd use its own logger instance so each
subsystem can have its own level specified independent of the others.

This is work towards #48.
2013-11-21 17:41:21 -06:00
Dave Collins
37d3d83ed3 Improve mempool handling.
- Lock the mempool when removing transactions during a notification as
  intended
- When generating the inventory vectors to serve on a mempool request,
  recheck the memory pool for each hash since it's possible another thread
  could have removed an entry after the initial query for available
  hashes
- When a block is connected, remove any transactions which are now double
  spends as a result of the newly connected transactions
2013-11-15 16:23:27 -06:00
Dave Collins
166f8c9ae5 Don't relay resurrected transactions.
This commit modifies the transaction memory pool handling so that it does
not relay resurrected transactions.  The other peers on the network will
also be reorganizing to the same block, so they already know about them.
2013-11-15 09:52:47 -06:00
Josh Rickmar
afc520634f Process all tx notifications, then notify new block.
This change allows wallet to record all transactions in a block before
receving the new block notification, and then process them all
together when the blockconnected notification arrives.
2013-11-12 14:50:33 -05:00
Dave Collins
70094fcee8 Minor cleanup.
Fix a couple of comments and call tx.Sha directly in a couple of places.
2013-10-30 14:13:29 -05:00
Dave Collins
08fc3050a3 Convert to use new btcutil.Tx and btcchain APIs.
This commit updates btcd to work with the new btcchain APIs which now
accept btcutil.Tx instead of raw btcwire.MsgTx.  It also modifies the
transaction memory pool to store btcutil.Tx.

This is part of the ongoing transaction hash optimization effort noted in
conformal/btcd#25.
2013-10-28 15:47:24 -05:00
Josh Rickmar
618b885e9e Notify wallets of mined transactions.
This change allows btcwallet to keep a pool of transactions that have
not yet been mined into a block, notifying wallet when transactions
are mined, as well as introducing a new way to send the
btcd:blockconnected notification with wallet-specific information as
part of the same notification.  When a transaction is sent using the
RPC call 'sendrawtransaction', a notification request will be
automatically registered with the connected wallet (if using
websockets) to notify the wallet when the transaction first appears in
a block.

To perform this notification, and to avoid requiring wallets from
waiting for seperate mined tx notifications (and resend after a
timeout) or from sending an additional tx mined request for every tx
in the pool after each new block, the blockconnected notification is
now created seperately for each wallet.  If the notified wallet has
sent a transaction, an additional JSON field "minedtxs" will include
an array of transaction IDs that the wallet has created and which are
included in the new block.

This new unique blockconnected notification can also be used for
additional notifications that may happen each new block in the future,
and to cut down on existing notification handlers in btcwallet, such
as for transactions to a watched address.
2013-10-23 18:13:03 -04:00
Owain G. Ainsworth
5a9cc91e62 Add an idle timer for peers.
If we don't hear from a peer for 5 minutes, we disconnect them. To keep
traffic flowing we send a ping every 2 minutes if we have not send any
other message that should get a reply.
2013-10-17 17:06:47 +01:00
Owain G. Ainsworth
a41c874837 Remove stale comment. 2013-10-17 17:06:47 +01:00
Owain G. Ainsworth
163b32887b Add blockmanager.current with extra checks for whether we are up to date.
This uses peer state to confirm if we are up to date, as well as what
chain thinks.
2013-10-17 17:05:18 +01:00
Josh Rickmar
a80f9da6c3 Add websocket handlers to the RPC server for wallet connections.
This change adds additional http listeners for websocket connections
on "/wallet".  Websockets are used to provide asynchronous messaging
between wallet daemons (i.e. btcwallet) and btcd as they allow an easy
way for btcd to provide instant notifications (instead of a wallet
polling for updates) and multiple replies to a single request.
Standard RPC commands sent over a websocket connection are handled
just like RPC, returning the same results, the only difference being
that the connection is async.  In cases where the standard RPC
commands fall short of wallet daemons requests, and to request
notifications for addresses and events, extension JSON methods are
used.

Multiple wallets can be connected to the same btcd, and replies to
websocket requests and notifications are properly routed back to the
original requesting wallet.

Due to the nature of turning a synchronous protocol asynchronous, it
is highly recommended to use the JSON id field as a type of sequence
number, so replies from btcd can be routed back to the proper handler
in a wallet daemon.
2013-10-14 13:37:48 -04:00
Dave Collins
6368d5b170 Respond to getdata requests for transactions.
This commit adds code to properly respond to getdata requests for
transactions by fetching them from the transaction pool.  Previously, we
advertised newly available transactions, but the code to respond with the
actual transaction was not written yet.

Also, fix a couple of comments and make the pushTxMsg and pushBlockMsg
functions consistent.
2013-10-11 14:14:55 -05:00
Dave Collins
3d62b24fe1 Reformat periodic block height ouput and add time.
Closes #9.
2013-10-10 18:24:23 -05:00
Dave Collins
9772626dd8 Improve logging.
This commit is a first pass at improving the logging.  It changes a number
of things to improve the readability of the output.  The biggest addition
is message summaries for each message type when using the debug logging
level.

There is sitll more to do here such as allowing the level of each
subsystem to be independently specified, syslog support, and allowing the
logging level to be changed run-time.
2013-10-10 17:22:19 -05:00
Dave Collins
e04986528c Add --nocheckpoints option.
This commit provides a new flag, --nocheckpoints, to disable built-in
checkpoints.

Checkpoints are used for a number of things such a ensuring
the block chain being downloaded matches various known good blocks,
allowing quicker verification on old blocks since scripts don't have to be
executed, and preventing forks from old blocks, etc.
2013-10-09 19:34:02 -05:00
Dave Collins
a0119b056e Move transaction handling into block manager.
The block manager handles inventory messges to know which inventory should
be requested based on what is already known and what is already in flight.
So, this commit adds logic to ask the transaction memory pool if the
transaction is already known before requesting it and tracks pending
requests into an in-flight transaction map owned by the block manager.

It also moves the transaction processing into the block manager so the
in-flight map can be properly cleaned.
2013-10-08 20:46:59 -05:00
Dave Collins
f4dac3abf0 Update to use latest btcwire invtype constants. 2013-10-08 15:55:07 -05:00
Dave Collins
c8160a57aa Switch to leveldb by default.
Also, add a warning if multiple block databases are detected.
2013-10-08 15:00:34 -05:00
Dave Collins
1d2c48555b Misc cleanup. 2013-10-07 19:24:44 -05:00
Dave Collins
4b728df738 Update some comments and code consistency. 2013-10-07 17:27:59 -05:00
Dave Collins
ca5c734e05 Add warning if there are no sync peers.
This is to help track down stalls that are being seen.
2013-10-07 17:09:33 -05:00
Dave Collins
995d8da491 Handle another removal case missed in prev commit.
Also, the loops which only remove a single element and break or return
don't need the extra logic for iteration since they don't continue
iteration after removal.
2013-10-07 10:10:22 -05:00
Dave Collins
219a6131f4 Correct all list/container loops that remove items.
It is not safe to remove an item from a container/list while iterating the
list without first saving the next pointer since removing the item nils
the internal list element's next pointer.
2013-10-07 09:06:29 -05:00
Dave Collins
efb54784c8 Log rejected blocks and transactions as info.
Rather than logging these as warnings which implies something is wrong
that might require user action, log them as info.
2013-10-04 13:35:28 -05:00
Dave Collins
78b555fcf9 Improve logging of rejected blocks.
Rather than showing all errors from ProcessBlock as a failure, check if
the error is a RuleError meaning the block was rejected as opposed to
something actually going wrong and log it accordingly.
2013-10-04 13:13:16 -05:00
Dave Collins
47c07ee5e1 Update a few comments. 2013-10-04 00:35:26 -05:00
Dave Collins
78e9b94d93 Implement transaction pool and relay.
This commit is a rather large one which implements transaction pool and
relay according to the protocol rules of the reference implementation.
It makes use of btcchain to ensure the transactions are valid for the
block chain and includes several stricter checks which determine if they
are "standard" or not before admitting them into the pool and relaying
them.

There are still a few TODOs around the more strict rules which determine
which transactions are willing to be mined, but the core checks which
are imperative (everything except the all of the "standard" checks really)
to operate as a good citizen on the bitcoin network are in place.
2013-10-03 22:31:54 -05:00
Dave Collins
3678153ae4 Allow regtest tool to be treated as a sync peer. 2013-10-03 22:31:00 -05:00
Owain G. Ainsworth
182c4d9ee6 Remove peers from duplicate map *before* we restart sync.
Just in case this ordering causes problems.
2013-10-03 20:13:56 +01:00
Owain G. Ainsworth
6bb0b80bbb Ignore non-sync invs and don't relay invs if we are not yet caught up.
We originally wanted to also not fetch orphan parents in this commit, however,
I have discovered that if you are doing a main sync from a peer, if it
sends you an orphan you must fetch it, else you ahven't fetched
everything it told you about and thus it will nto send you end more invs
from the main sync.

So we always fetch orphan parents, but we still don't fetch from
non-sync peers (all invs from them will be unsolicited). Seems to fix some hangs
with multiple peers.
2013-10-03 20:13:56 +01:00
Dave Collins
6dbc61e960 Remove the noverify option.
This was a development only option.
2013-10-03 13:01:18 -05:00
Dave Collins
0c6b79afb0 Don't disconnect on unrequested blocks for regtest.
The "official" regression test tool intentionally sends some unrequested
duplicate blocks to ensure the chain handling code does not fail when
trying to insert them.  This commit adds an exception to the block manager
which typically disconnects peers that send unrequested blocks (they are
misbehaving if they do this) for regression test mode.
2013-10-03 11:21:41 -05:00
Dave Collins
bd3a39ad4a Fix comment typo. 2013-10-03 11:10:57 -05:00
Owain G. Ainsworth
2b56e7a397 Don't need the blockpeermutex anymore.
Really, it would be nice to pass an interface{} into chain to be given
to us when the callback calls, it would avoid the awkward sidchanneling
through the map and should actually be more efffieint (pointer passing >
hashtable insert, lookup, then remove).
2013-10-03 16:13:47 +01:00
Dave Collins
fd0679acdd Update notification for recent btcchain API change. 2013-10-02 21:21:52 -05:00
Dave Collins
29dfa22086 Introduce a Stringer on peers.
Rather than having all of the various places that print peer figure out
the direction and form the string, centralize it by implementing the
Stringer interface on the peer.
2013-10-02 20:05:10 -05:00
Dave Collins
f1e2de4f0c Go fmt. 2013-10-02 19:44:07 -05:00
Dave Collins
52701d826d Add directionality back to remove peer log too. 2013-10-02 19:43:38 -05:00
Owain G. Ainsworth
13a8a8e7e3 use directionString() instead of handrollong. 2013-10-03 01:39:31 +01:00
Owain G. Ainsworth
2dcd003722 Print if a peer is inbound or outbound.
This got lost in the peer logging rework. Pointed out by davec@.
2013-10-03 01:21:30 +01:00
Owain G. Ainsworth
eb667fdf83 Remove races on chain.
Chain is not concurrency safe, so we move the chainNotifySink handling
into the main blockmanager goroutine. Due to a possible deadlock if the
buffer is filled this still has to be a single channel that isn't linked
to the other ones. There is a possible starvation issue where the main
msgChan gets selected more often than the  notification sink, but until
chain is concurrency safe this is rather unavoidable.
2013-10-03 00:50:36 +01:00
Owain G. Ainsworth
8974e789f7 Convert the rest of the subsystems to use atomics for shutdown vars. 2013-10-03 00:33:42 +01:00
Owain G. Ainsworth
f333cb4220 Remove a (largely harmless) race on p.conn
Add a Connected() member function that checks atomic variables to see if
the peer is connected.
2013-10-02 23:06:29 +01:00
Owain G. Ainsworth
5c1340be8f make logging about peers rather quieter.
Only log errors for most cases if the peer is persisent (and thus requested).
Only log by default after version exchange, and after losing a peer that had
completed version exchange. Make most other messages debug.
2013-10-02 22:50:24 +01:00
Owain G. Ainsworth
7eb1a5ce4e Disconnect misbehaving peers who send unsolicited blocks. 2013-10-02 14:36:04 +01:00
Owain G. Ainsworth
65725189db Keep track of currently requested blocks per peer.
Use this information so that we do not request a block per peer we got
an inv for it, makes multi peer much quieter and rather more bandwidth
efficient.

In order to remove a number of possible races we combine blockhandling
an synchandler and use one channel for all messages. This ensures that
all messages from a single peer will be recieved in order.  It also
removes the need for a lot of locking between the peer removal code and
the block/inv handlers.
2013-10-02 14:36:04 +01:00
Owain G. Ainsworth
ca7cb8c875 move the intiial chain cache generation into bm.
Blockmanager is otherwise the only current consumer of chain and it is
messy to do it outside of it.
2013-10-02 14:36:04 +01:00
Dave Collins
ea256aeb5a Update a few comments. 2013-09-29 15:26:25 -05:00
Dave Collins
9880cf4646 Improve chain notification handling.
Previously a new goroutine was launched for each notification in order to
avoid blocking chain from continuing while the notification is being
processed.  This approach had a couple of issues.

First, since goroutines are not guaranteed to execute in any given order,
the notifications were no longer handled in the same order as they were
sent.  For the current code, this is not a problem, but upcoming code that
handles a transaction memory pool, the order needs to be correct.

Second, goroutines are relatively cheap, but it's still quite a bit of
overhead to launch 3-4 goroutines per block.

This commit modifies the handling code to have a single sink executing in
a separate goroutine.  The main handler then adds the notifications to a
queue which is processed by the sink.  This approach retains the
non-blocking behavior of the previous approach, but also keeps the order
correct and, as an additional benefit, is also more efficient.
2013-09-28 22:13:22 -05:00
Dave Collins
f1cd96ceb5 Update a few comments. 2013-09-26 21:06:01 -05:00
Owain G. Ainsworth
b97db056c1 Move the inventory handling from peer into blockmanager.
This removes a horrible case of reach-around from per into the guts of
the blockmaanger to frob the chain. Soon, when we try to deduplicate the
fetching of blocks from multiple peers this will need decisions made in
a central point.

Discussed at length with davec.
2013-09-27 01:51:05 +01:00
Dave Collins
a69647b94d Handle notifications from chain in own goroutine.
This change is in response to the recent change in btcchain such that
notifications are no longer sent in their own goroutine.
2013-09-21 09:57:47 -05:00
Dave Collins
92a8605b24 Continue work on addrmgr and multi-peer.
- Remove leftover debug log prints
- Increment waitgroup outside of goroutine
- Various comment and log message consistency
- Combine peer setup and newPeer -> newInboundPeer
- Save and load peers.json to/from cfg.DataDir
- Only claim addrmgr needs more addresses when it has less than 1000
- Add warning if unkown peer on orphan block.
2013-09-17 10:48:47 -05:00
Dave Collins
79bb334b9a Remove old regression test db in regtest mode.
The regression test mode is special in that the 'official' block test
suite requires an empty database to work properly.  Rather than having to
manual go delete it before each test, add code to automatically delete the
old regression test database when in regression test mode.
2013-09-15 16:58:02 -05:00
Dave Collins
629a1c9d06 Rework the data path and db type handling.
This commit modifies the way the data paths are handled.  Since there will
ultimately be more data associated with each network than just the block
database, the data path has been modified to be "namespaced" based on the
network.  This allows all data associated with a specific network to
simply use the data path without having to worry about conflicts with data
from other networks.

In addition, this commit renames the block database to "blocks" plus a
suffix which denotes the database type.  This prevents issues that would
otherwise arise if the user decides to use a different database type and
a file/folder with the same name already eixsts but is of the old database
type.  For most users this won't matter, but it does provide nice
properties for testing and development as well since it makes it easy to
go back and forth between database types.

This commit also includes code to upgrade the old database paths to the
new ones so the change is seamless for the user.

Finally, bump the version to 0.2.0.
2013-09-15 14:25:32 -05:00
Dave Collins
1c9a7095b3 Change --dbdir flag to --datadir.
This change paves the way for saving more than just the block database to
the filesystem (such as address manager data, index data, etc) where the
name "dbdir" no longer makes sense.
2013-09-13 18:02:10 -05:00
Dale Rahn
af7aa39624 Allow config file and command line to select between sqlite and levdldb 2013-09-13 10:08:19 -04:00
Dave Collins
33b65f943f Increment waitgroups before goroutines are started.
This commit changes the code so that all calls to .Add on waitgroups
happen before the associated goroutines are launched.   Doing this after
the goroutine could technically cause a race where the goroutine started
and finished before the main goroutine has a chance to increment the
counter.  In our particular case none of the goroutines exit quickly
enough for this to be an issue, but nevertheless the correct way should be
used.
2013-09-12 17:24:37 -05:00
Dave Collins
e4577ab5f4 Syncrhonize access to the blockPeer map. 2013-09-12 12:10:48 -05:00
Dave Collins
121f7a47d4 Add block inventory relay.
This commit adds support for relaying blocks between peers.  It keeps
track of inventory that has either already been advertised to remote peers
or advertised by remote peers using a size-limited most recently used
cache.  This helps avoid relaying inventory the peer already knows as
much as possible while not allowing rogue peers to eat up arbitrary
amounts of memory with bogus inventory.
2013-09-11 20:14:13 -05:00
Dave Collins
adf7149838 Update for recent btcchain orphan notify change. 2013-09-09 19:58:38 -05:00
Dave Collins
afddca6870 Use log.Errorf for error messages with params. 2013-09-09 10:59:31 -05:00
Dave Collins
cbfee93b74 Modify syncing code to support multiple peers.
Previously the code was only designed to work with a single peer.  This
commit modifies the syncing code to deal with multiple peers.
2013-09-04 10:10:00 -05:00