Commit graph

100 commits

Author SHA1 Message Date
Dave Collins
e3f3918242 Use increment on p.retryCount to make golint happy. 2014-03-19 17:58:58 -05:00
Owain G. Ainsworth
aff33f1e3c Consistently use the peer stringer to print the peer address.
This provides more information than using the address directly.
2014-03-04 15:47:20 +00:00
David Hill
cbb5c5b424 recieve -> receive 2014-03-02 13:28:29 -05:00
Dave Collins
91e563edaa Add IP address to a few more peer error messages.
This commit adds the peer IP to a few more error messages as originally
noted by #102.
2014-02-28 10:59:35 -06:00
Dave Collins
ce2f68a982 Fix typo on previous commit.
The peer and error were reversed for the regression test error message
case.

Spotted by @dajohi.
2014-02-28 10:55:25 -06:00
Dave Collins
29b790b9c8 Add IP address to peer error messages.
Closes #102.
2014-02-28 10:48:50 -06:00
Dave Collins
3a195b9100 Remove duplicate PEER prefix from peer logging.
These were left over from the switch to the logging subsystems which
include the prefix as a part of the subsystem.
2014-02-14 12:45:33 -06:00
Dave Collins
e5a1c6e5ac Use mutexes for byte counts to fix i386/arm panic.
This commit changes the server byte counters over to use a mutex instead
of the atomic package.  The atomic.AddUint64 function requires the struct
fields to be 64-bit aligned on 32-bit platforms.  The byte counts are
fields in the server struct and are not 64-bit aligned.  While it would be
possible to arrange the fields to be aligned through various means, it
would make the code too fragile for my tastes.  I prefer code that doesn't
depend on platform specific alignment.

Fixes #96.
2014-02-13 09:58:19 -06:00
Dave Collins
6f063e0c1b Update byte counts unconditionally.
Rather than updating the byte counts in the error path and after the error
path, do it unconditionally before checking the error.
2014-02-05 11:50:40 -06:00
Dave Collins
c51df0ca3c Don't assign result from atomic.AddUint64. 2014-02-05 11:44:07 -06:00
Dave Collins
a39f4a0698 Correct total byte counters for server.
Previously the getnettotals was just looping through all of the currently
connected peers to sum the byte counts and returning that.  However, the
intention of the getnettotals RPC is to get all bytes since the server was
started, so this logic was not correct.

This commit modifies the code to keep an atomic counter on the server for
bytes read/written and has each peer update the server counters as well as
the per-peer counters.
2014-02-05 11:15:41 -06:00
Dave Collins
f8c843e2e3 Rename bytesRead/Written to bytesReceived/Sent.
This makes it a little more clear the variables reprsent bytes sent across
the network as opposed to from disk.
2014-02-04 22:37:13 -06:00
Dave Collins
591b0f431d Switch over to new btcwire Read/WriteMessageN.
This commit adds byte counters to each peer using the new btcwire
ReadMessageN and WriteMessageN functions to obtain the number of bytes
read and written, respectively.  It also returns those byte counters via
the PeerInfo struct which is used to populate the RPC getpeerinfo reply.

Closes #83.
2014-02-04 00:00:13 -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
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
Owain G. Ainsworth
9cb5190ac2 add support for the ping rpc command.
And the pingtime and pingwait fields of getpeerinfo.
2014-01-22 16:21:08 +00:00
Dave Collins
f309e899f3 Make use of the new btcdb functions.
This commit switches the handleGetHeadersMsg function to make use of the
new FetchBlockHeightBySha and FetchBlockHeaderBySha functions in btcdb.

Also, while here, nuke the header copy which is no longer required due to
the recent btcwire changes.
2014-01-19 03:05:02 -06:00
Dave Collins
33bb455365 Update for recent btcwire API changes. 2014-01-18 21:15:09 -06:00
Dave Collins
7ad6e235ad Reduce the initial idle timeout to 30 seconds.
This commit reduces the initial idle timeout before version negotiation
has happened on a new peer to 30 seconds.  Previously it could take 5
minutes due to the general idle timeout.
2014-01-18 01:44:34 -06:00
Dave Collins
d33e9b4165 Unexport and comment btcDial and btcLookup func.
These functions are at the package level and only apply within btcd, so
unexport them to be consistent.
2014-01-10 01:31:20 -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
Owain G. Ainsworth
dd7c910e86 Enable use of a different proxy for .onion addresses.
This implements --onion (and --onionuser/--onionpass) that enable a
different proxy to be used to connect to .onion addresses. If no main
proxy is supplied then no proxy will be used for non-onion addresses.

Additionally we add --noonion that blocks connection attempts to .onion
addresses entirely (and avoids using tor for proxy dns lookups).

the --tor option has been supersceded and thus removed.

Closes #47
2014-01-07 19:18:09 +00: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
Owain G. Ainsworth
d3a7f15a87 Alter the way peers queue outbound messages somewhat.
Instead of one thread that queues and writes, we move to a two queue
model. The queueHandler muxes all the sources of outgoung packets and
drips them to the actual sender. This is done so that a large send
doesnt' allow the channels to fillup and cause blockmanager and server
to block, which delays other peers.

Most messages we handle as is. However, for getdata we do some manual
limiting and pipelining, we queue up three and then we load the next
into memory, not sending it until the otherp ackets have been sent. We
may want to change this later to queue the packet *then* wait so that we
don't completely drain the pipe.

A few misc tweaks to avoid deadlocking by ensuring the all channels will
always drain. mostly this relates to ensuring that we know no more data
will be coming before we drain the channel, and not queueing after we
are marked to disconnect.

Discussed heavily with drahn@ and davec@.
2013-12-23 23:51:52 +00:00
Owain G. Ainsworth
2c81f61616 Also drain the inv channel as well as the message channel on peer quit.
Shold prevent a deadlock where we exit but server/blockmaanger is
waiting on our inv channel.

Closes #62
2013-12-17 15:51:37 +00: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
Owain G. Ainsworth
d2d899d157 pushVersionMessage: fix you/me address generation
The you address is the one we already set up fo the user, so either waht
we connected to (this will work with tor, etc), or the ip the user
connect to us from otherwise. We must however check to see if it is the address
of the proxy and strip it.

The me addesss, we use the same address selection for local addresses as
always

This should mean that we pass our tor address out in the version message
and thus the peers should add us to their addressmanager.
2013-12-10 19:39:47 +00:00
Owain G. Ainsworth
f93203b91e Initial basic support for selection of external ip address.
This implements only the bare bones of external ip address selection
using very similar algorithms and selection methods to bitcoind. Every
address we bind to, and if we bind to the wildcard, every listening
address is recorded, and one for the appropriate address type of the
peer is selected.

Support for fetching addresses via upnp, external services, or via the
command line are not yet implemented.

Closes #35
2013-12-10 19:39:47 +00:00
Owain G. Ainsworth
1e836d26f4 Handle tor and dns-name addresses.
Perform the requisite processing on .onion addresses to turn them into the tor
reserved ipv6 region (the same as bitcoind and onioncat). Furthermore,
when printing an ip address, reverse the conversion so we print it
nicely.  base32 as standard is uppercase, but tor and bitcoind seem to
use lowercase so we  first must for we force .onion addrs to uppercase
(and to lowercase on the reverse).

As a side effect we now should handle dns names on the command line (via tor if
required) and add them to the addressmanger as necessary.
2013-12-10 19:39:46 +00:00
Owain G. Ainsworth
a3d783e9e8 set up p.na before preparing our reply version message.
Means we can use that instead of generating another (next commit).
2013-12-10 19:39:46 +00:00
Dave Collins
c8e88d383e Correct issue with pushing address messages.
The code to send an address messages in batches was previously clearing
all addresses from the existing message after queueing it to be sent.
Since the message is a pointer, this means it was removing the addresses
from the same message which might not have already been sent yet (from
another goroutine) which led to a race.

This commit modifies the code to create a new address message for each
batch as intended.

Fixes #58.
2013-12-10 09:13:16 -06: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
Owain G. Ainsworth
41d2d36643 Only update p.na on reciept of version message for inbound peers.
Outbound we already have the exact same thing set up, and this should
quieten the race detector. Please note that this does *not* cause
problems with the service flags being wrong. Since by this point we have
already done every thing that would use the service flags from p.na in
addrmanager, and now p.Services is correct..
2013-11-21 19:19:17 +00: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
David Hill
4f25d45e77 Grab the remote peer's user agent. 2013-10-29 21:45:45 +00:00
Owain G. Ainsworth
b1f14732b1 Implement getpeerinfo and getconnectedcount
We have a channel for queries and commands in server, where we pass in
args and the channel to reply from, let rpcserver use these interfaces
to provide the requistie information.

So far not all of the informaation is 100% correct, the syncpeer
information needs to be fetched from blockmanager, the subversion isn't
recorded and the number of bytes sent and recieved needs to be obtained
from btcwire. The rest should be correct.
2013-10-29 17:05:12 +00:00
Owain G. Ainsworth
d647eea2b7 update statistics for the time we last send/recieved a message. 2013-10-29 17:02:04 +00:00
Owain G. Ainsworth
d26b8b2d43 Set peer.timeConnected when we are actualy connected. 2013-10-29 17:02:04 +00: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
David Hill
0abfdcc88b fix reversed variables in a warning message. 2013-10-17 16:58:57 -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
bc89dedf9a Remove prevGetBlocksMutex.
This is only ever accessed from one place (blockmanager) which is single
threaded.
2013-10-17 17:06:47 +01:00
Owain G. Ainsworth
2231456c23 Make it possible to get a notification when a message has been sent.
If a channel is passed in then true will be sent on the provided channel
after the message has successfully sent.
2013-10-17 17:06:41 +01:00
Owain G. Ainsworth
178d9dc7b0 Peer: use QueueMessage instead of directly using the channel. 2013-10-17 17:05:21 +01:00
Dave Collins
14f81aa479 Add handler for notfound messages.
For now, these are ignored, but ultimately they should be used to
re-request the missing inventory from another peer.
2013-10-15 10:35:42 -05:00
Owain G. Ainsworth
0536e3104c Don't send messages before handshake.
If we haven't handshaken with a peer don't send messages that are not
the handshake. Additionally don't queue up invs for sending, they'll
find out soon enough when they ask us what we know.
2013-10-14 22:27:48 +01: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
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