Commit graph

76 commits

Author SHA1 Message Date
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
Dave Collins
54b5cb56e7 Move logger code into its own file.
This cleans up btcd.go a bit and consolidates the logging related
functions.  It also paves the way for upcoming message summaries.
2013-10-10 14:36:05 -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
cd68e3060f Remove extra msg in log message. 2013-10-08 17:45:05 -05:00
Dave Collins
f4dac3abf0 Update to use latest btcwire invtype constants. 2013-10-08 15:55:07 -05:00
Dave Collins
67838afb20 Go fmt and comments. 2013-10-08 13:34:04 -05:00
Dave Collins
697532bd68 Add handling for mempool command. 2013-10-08 00:04:51 -05:00
Dave Collins
19d28f90e6 Log transactions rejected from mempool as debug.
Most users won't care if a freestanding transaction is rejected from due
to a rule violation, but the information should still be available to
debug.
2013-10-07 18:45:53 -05:00
Dave Collins
8e12234c56 Fix a couple of comments. 2013-10-05 17:40:54 -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
223d146a10 Improve logging of rejected transactions.
Rather than showing all errors from ProcessTransaction as a failure, check
if the error is a TxRuleError meaning the transaction was rejected as
opposed to something actually going wrong and log it accordingly.
2013-10-04 13:33:54 -05:00
Dave Collins
c3a17de326 Comment Connected function in peer.
While here, also rearrange the functions slightly to logically group them.
2013-10-04 10:45:21 -05:00
Owain G. Ainsworth
96b92552b9 Can't use Connected() in Disconnect since it just set disconnected.
Use p.connected directly. This restores the correct disconnection of peers when
we go over the limit. Found by dhill, fix by me.
2013-10-04 15:05:31 +01: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
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
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
98109dbadd Fix shutdown hangs.
We would occasionally hang or a while during server shudown, this is due
to an outbound peer waiting on a connection or a sleep. However, we
don't actually require to wait for the peers to finish at all. So just
let them finish.

Secondly, make peer.disconnnect and server.shutdown atomic varaibles so
that checking them from multiple goroutines isn't race, and clean up
their usage.
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
850420055f Bucketizing for addrmanager
Implement the bucketing by source group and group using essentially the
same algorithm as the address maanger in bitcoind.

Fix up the saving of peer.json to do so in a json format that keeps bucket
metadata.

If we fail to load the some of the data we asssume that we have
incomplete information, so we nuke the existing file and reinitialise so
we have a clean slate.
2013-10-02 14:35:59 +01:00
Owain G. Ainsworth
989e7a9c48 Make error logging in peer.go unique.
Helps tracking down errors.
2013-10-02 14:35:58 +01: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
Todd T. Fries
790ba87979 reset retrycount upon successful connection 2013-09-26 16:52:05 -05:00