Commit graph

38 commits

Author SHA1 Message Date
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
Todd T. Fries 1e77c8e554 update with knits from davec and an additional one from me 2013-09-26 16:45:10 -05:00
Todd T. Fries 568c0044a0 introduce a backoff behavior for peers that are not permitting connections
with help from davec

o implement peer { retrycount int64 ..
o count connect failures per peer
o calculate backoff as 10s * retrycount / 2
2013-09-26 16:26:31 -05:00
Dave Collins 346ff6f9e2 Filter duplicate getblocks requests.
This commit adds detection and filtering for back-to-back duplicate
getblocks requests.  This is needed because the trigger for requesting
more blocks is receiving an orphan.  When the peer is further behind than
the number of blocks advertised via a single inventory message, the same
orphan block will be sent multiple times.  When the peer receives the
final inventory message, it too contains the orphan that was previously
sent.  This leads to a duplicate getblocks request that must be filtered
to prevent requesting the final series of blocks again.
2013-09-18 13:33:54 -05:00
Dave Collins 3ca1e82f66 Make go vet happy. 2013-09-18 00:27: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
Owain G. Ainsworth 6c05e9d475 Flesh out addrmanger with some basic functionality.
Use it to add multiple peer support. We try and keep 8 outbound peers
active at all times.

This address manager is not as complete as the one in bitcoind yet, but
additional functionality is being worked on.

We currently handle (in a similar manner to bitcoind):

- biasing between new and already tried addresses based on number of connected
  peers.
- rejection of non-default ports until desparate
- address selection probabilities based on last successful connection and number
  of failures.
- routability checks based on known unroutable subnets.
- only connecting to each network `group' once at any one time.

We currently lack support for:
- tor ``addresses'' (an .onion address encoded in 64 bytes of ip address)
- full state save and restore (we just save a json with the list of known
  addresses in it)
- multiple buckets for new and tried addresses selected by a hash of address and
 source.  The current algorithm functions the same as bitcoind would with only
 one bucket for new and tried (making the address cache rather smaller than it
 otherwise would be).
2013-09-15 20:25:55 -05:00
Dave Collins 69efe46eb5 Fix a comment typo and comment outputBufferSize. 2013-09-12 12:11:46 -05:00
Dave Collins f5c03696f7 Remove relay log message and update comment. 2013-09-12 09:29:42 -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 afddca6870 Use log.Errorf for error messages with params. 2013-09-09 10:59:31 -05:00
Dave Collins cf7438a646 Rework getblocks handling.
This commit reworks the getblocks handling a bit to clean it up and match
the reference implementation handling.  In particular, it adds monitoring
for when peers request the final block advertised from a previous
getblocks message and automatically avertises the latest known block
inventory to trigger the peer to send another getblocks message.
2013-09-05 01:25:52 -05:00
Dave Collins 83a9bbd4dd Update getheaders unknown block locator handling.
When no blocks in the block locator are found, start with the block after
the genesis block.  This means the client will start over with the genesis
block if unknown block locators are provided.  This mirrors the behavior
in the reference implementation.
2013-09-04 20:46:44 -05:00
Dave Collins f07d427837 Rework and correct getheaders handling.
This commit reworks the getheaders handling a bit to clean it up and match
the reference implementation handling.  In particular, in addition to the
normal handling where headers starting after the block locator up to the
stop hash are served, when no locator hashes are provided, the stop hash
acts as a way to specifically request that header.  Next, an empty headers
message is sent when no hashes provided by the block locator can be
found.  Finally, there was a bug that was limiting the number of headers
that could requested at once to 500 instead of the expected 2000.
2013-09-04 18:17:42 -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
Dave Collins a69ba92006 Set services to remote peer services for all peers.
Rather than only setting the services field for inbound peers, set it for
all peers.  This field referes to the remote peer's services regardless of
inbound or outbound.
2013-09-03 13:34:27 -05:00
Dave Collins 83407ade61 Rework block fetching code.
This commit significantly reworks the fetching code to interop better with
bitcoind.  In particular, when an inventory message is sent, and the
remote peer requests the final block, the remote peer sends the current
end of the main chain to signal that there are more blocks to get.

Previously this code was automatically requesting more blocks when the
number of in-flight blocks was under a certain threshold.  The original
approach does help alleviate delays in the "request final, wait for
orphan, request more" round trip, but due to the aforementioned mechanism,
it leads to double requests and other subtle issues.
2013-08-30 13:04:50 -05:00
Dave Collins 6acd51f4b4 Only advertise local addr to peers when listenting.
Do not advertise the local address to outbound peers when we aren't
listening and therefore able to accept connections.
2013-08-17 15:26:51 -05:00
Dave Collins 60779ea8df Add message blocking semantics to block processing.
This commit modifies the input message handler so that when a remote peer
sends a block, no further messages from that peer are accepted until the
block has been fully processed and therefore known good or bad.  This
helps prevent a malicious peer from queueing up a bunch of bad blocks
before disconnecting (or being disconnected) and wasting memory.

Additionally, this behavior is depended on by at least the block
acceptance test tool as the reference implementation processes blocks in
the same thread and therefore blocks further messages until the block has
been fully processed as well.
2013-08-16 13:40:05 -05:00
Dave Collins 2570ecd2ac Move log closure code into its own file. 2013-08-10 20:07:37 -05:00
Dave Collins f269ad2ff4 Comment the logClosure code. 2013-08-09 16:02:47 -05:00
Dave Collins 8634a2fa01 Refactor peer disconnect code into single func. 2013-08-09 15:57:13 -05:00
Dave Collins 41910c0944 Import needed package. 2013-08-08 10:11:03 -05:00
Dave Collins 1fecbec3df Move userAgent to peer where it's used. 2013-08-08 09:26:18 -05:00
Dave Collins 9a9f41a2f3 Modify code to use proxy aware NetAddresses.
This paves the way for support with proxied connections.
2013-08-07 23:53:19 -05:00
Dave Collins 0d7bff2444 Remove some unused code. 2013-08-07 23:44:04 -05:00
Dave Collins 8574846e87 Move btcd to root directory.
This allows easier go get paths.
2013-08-07 12:47:51 -05:00
Renamed from btcd/peer.go (Browse further)