-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Peer/Host restructuring #315
Conversation
Travis is getting DB errors that I wasn't getting locally, so I'll have to look into those. It compiles, runs, and passes tests for me locally in its current state although I did need to drop all my xud databases. Edit: Looks like the issue is Travis is using mysql 5.5, which doesn't support the JSON data type I'm using for storing node addresses. I can fix the Travis build, I just want to make sure it's not unreasonable to require 5.7 mysql. It was released almost 3 years ago so I think it's fine. Second Edit: After a bit more research, Debian stretch by default uses MariaDB 10.1 for it's MySQL variant, which doesn't support the JSON data type. Rather than have to worry about installing special versions of software on popular variants, I'll figure out another approach. For testing purposes this should still work fine on MySQL 5.7+ and MariaDB 10.2.7+. |
a8e5522
to
180ae97
Compare
I fixed the DB dependency issue that was causing travis to fail by changing the column to a TEXT type named
|
180ae97
to
bcbda53
Compare
bcbda53
to
789fccd
Compare
instructions-for-devs.md
Outdated
@@ -142,12 +144,15 @@ host = "localhost" | |||
|
|||
[p2p] | |||
listen = true | |||
port = 8885 | |||
#make sure this port is reachable from the internet | |||
port = 8885 # Make sure this port is reachable from the internet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Make sure this port is reachable from the internet
Maybe we can phrase this differently and refer to firewalls and does that port have to be reachable when you just want to have outbound connections?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another comment about this subject:
The listen port may not be the port which is open on the firewall. for example, xud may listen on 8885 but the firewall may open 8888 and have port forwarding role from 8888 to 8885 on the xud machine. This is a very common situation (just consider 2 servers behind the FW running xud).
As such we must have a listen port and an external port which we publish to the peers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@offerm I think this is already handled in this PR by p2p.addresses
. There you can specify the port that is sent in the handshake for each address.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A string array of reachable socket addresses for this node, port defaults to p2p.port if unspecified
addresses = [ "4.8.15.16:8885" ]
Well done @sangaman , that's exactly how it should be! This will allow even people in heavily censored countries to propagate p2p.addresses
with port e.g. 443
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kilrau The port has to be between 1024
and 65535
. But there are still plenty options to choose from.
And when you are in a heavily censored country changing the port won't help you much. Maybe we can provide a tutorial for setting up XUD with Tor in the future.
instructions-for-devs.md
Outdated
port = 8885 | ||
#make sure this port is reachable from the internet | ||
port = 8885 # Make sure this port is reachable from the internet | ||
# A string array of reachable socket addresses for this node, port defaults to 8885 if unspecified |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the default port be the config value p2p.port
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be good, yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job, looks good in the overall.
Making the pubkey as the main identifier definitely make things simpler. We just need to make sure it doesn't put unnecessary constrains.
lib/p2p/Pool.ts
Outdated
public addOutbound = async (socketAddress: SocketAddress): Promise<Peer> => { | ||
if (this.peers.has(socketAddress)) { | ||
const err = errors.ADDRESS_ALREADY_CONNECTED(socketAddress.address); | ||
public addOutbound = async (address: Address, nodePubKey: string): Promise<Peer> => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do I must know the nodePubKey in order to connect to a node? it obviously helps to have it as the pk, but do we want to put the constrain of identifying a node by ip+port+pubkey, and not just ip+port?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's completely necessary, and actually in my first approach I didn't add the pk to the connect
gRPC method, but it seemed worth it to me. The advantage is we know who we're connecting to, meaning that we can tell before even attempting the connection if we are already connected, and that we know which pk to expect from the handshake. In cases where we already know the pk, either from saved nodes or nodes we hear about from other peers, there's no downside. For the gRPC method it makes the command a bit more cumbersome particularly from the cli, but I still thought it made sense for purposes of knowing right away if we are already connected. This is also the approach lnd
uses, connecting requires specifying the node pub key up front.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, so let’s just wait for @kilrau to approve this (in case he didn’t already)
lib/db/models/Node.ts
Outdated
return JSON.parse(this.addressesText); | ||
}, | ||
set(this: db.NodeInstance, value: Address[]) { | ||
this.setDataValue('addressesText', JSON.stringify(value)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JSON column type would have been good, but if it's not supported, why not to normalize it into a separate table?
The downside of the current approach is mainly that it's not possible to query a node via address
, because you must deserialize everything first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hadn't thought of that but it does make querying for node via address awkward (I think it could still be possible with SELECT * WHERE addresses LIKE '%host:'1.2.3.4',port:8885%
, but not the nicest query).
The advantage as I see it is that addresses
can be updated with a single, simple UPDATE query on handshake and it makes loading nodes from the db a little simpler because it's just querying rows from a single table. But if querying node via address is something we'll do regularly, it should probably be changed. I can't think of a real need to query node by address off the top of my head, can you?
As an aside, updating the addresses on handshake is actually not something that's implemented in this PR. So I will either take care of that here or in a separate PR after this is merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Main scenario for querying by address would be to block an inbound peer, prior to handshake, based on the node entity (see my other comment). We might end up having other usages as well.
Squashing a many-to-one relationship in a row is a known problem in RDBMS, forcing you to normalize. This is why MongoDB became popular, followed by the JSON columns (PostgreSQL and then MySQL).
Concatenating the array is usually a fine for a dumb column, one that you wouldn't do anything with except projecting. Yes, querying would be possible, but pretty awful.
At the moment, even if we'll want to query by address, we'll do it in-memory (after deserializing), so no DB support is needed. So I guess you can leave this situation as-is for now, and change it if we'll need to.
peer.setHost(host); | ||
private handleOpen = async (peer: Peer): Promise<void> => { | ||
if (this.nodes.isBanned(peer.nodePubKey!)) { | ||
// TODO: Ban IP address for this session if banned peer attempts repeated connections. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you plan to ban IP addresses prior to handshake, or here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in both places, or rather right after the handshake. The if statement here is supposed to catch peers who are banned who connect to us anyway. The Peer class doesn't know about which nodes are banned which is why the logic is here. But I think if the handshake is bad or invalid, we can also put logic to ban before emitting the open
event.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were talking earlier about blocking inbound peers prior to handshake, based on IP address. Just wanted to know if we plan to support that, because if we do, we'll need to query nodes by IP address. If we don't, we're more vulnerable to DDoS.
This doesn't apply for banning within session, if we'll just collect banned IP addresses.
But we might want to apply this to blacklist/whitelist modes, which should persist, and might refer to a node entity - not strictly an IP address.
But anyway, we'll deal with that when we'll get to it.
lib/p2p/SocketAddress.ts
Outdated
return { | ||
host: this.host, | ||
port: this.port, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why using both SocketAddress
& Address
, if you already renamed some of the codebase to Address
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's perhaps a bit confusing, I tried to explain in comments but maybe I need to make it more clear. SocketAddress
is a class with a handy toString
method. Address
is just a type representing the host+port tuple. Maybe we can drop SocketAddress
though and just use Address
plus a utils method to convert an Address to the host:port string we use in several places though.
lib/p2p/Peer.ts
Outdated
@@ -416,17 +414,23 @@ class Peer extends EventEmitter { | |||
|
|||
this.socket.once('close', (hadError) => { | |||
// emitted once the socket is fully closed | |||
if (hadError) { | |||
this.logger.warn(`Socket closed due to error (${this.id})`); | |||
if (this.nodePubKey === undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as discussed in #327, I think it would be good to log pre-handshake socket close only if connection was already established.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, but keep the verbose
log if we're connected but pre-handshake?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be on info
, same as the other non-error disconnection
lib/p2p/NodeList.ts
Outdated
/** | ||
* Return a [[NodeInstance]] array for nodes that haven't been banned. | ||
*/ | ||
public toArray = (): NodeInstance[] => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not in usage
lib/p2p/NodeList.ts
Outdated
/** | ||
* Return a [[NodeFactory]] array for nodes that haven't been banned and have known addresses. | ||
*/ | ||
public toFactoryArray = (): NodeFactory[] => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using the Factory
term here is a bit confusing, because it's from the DB row context. Maybe create a different type, with the same properties.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true, so basically create an alias for the type? I'll look into it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, something like this.
lib/p2p/Pool.ts
Outdated
await this.nodes.load(); | ||
this.nodes.forEach((node) => { | ||
this.connectNode(node); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
connecting to banned nodes as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, I'll fix this. I'll probably put the logic in one place since similar logic is also being used on receiving a NODES
packet.
lib/p2p/Pool.ts
Outdated
private connectNode = async ({ addresses, nodePubKey }: NodeFactory) => { | ||
for (let n = 0; n < addresses.length; n += 1) { | ||
try { | ||
await this.addOutbound(addresses[n], nodePubKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why connecting to all the node's addresses? if one succeed, isn't it sufficient? specially if they are all using the same pubkey.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch as well, I thought I'd put a break
statement here but apparently not.
789fccd
to
2571e58
Compare
Conflicts resolved and suggested changes addressed, there are still a few open questions to @moshababo. I created a type alias called |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few more minor details.
instructions-for-devs.md
Outdated
--rpc.port, -r gRPC service port [number] | ||
--webproxy.disable Disable web proxy server [boolean] | ||
--webproxy.port Port for web proxy server [number] | ||
>>>>>>> 789fccd... update readme |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You overlooked some conflicts here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'll fix it.
|
||
export default (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) => { | ||
const attributes: db.SequelizeAttributes<db.NodeAttributes> = { | ||
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason the nodePubKey
is not the primaryKey
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eventually we'll have a table to track node reputation events - and perhaps more tables to track successful trade history or other information related to nodes - and being able to use an integer id
as a foreign key will be better for those tables.
lib/p2p/Peer.ts
Outdated
@@ -122,13 +108,19 @@ class Peer extends EventEmitter { | |||
|
|||
public getStatus = (): string => { | |||
if (this.connected) { | |||
return `Connected to peer (${this.id})`; | |||
return `Connected to peer ${this.socketAddress.toString()}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The public key of the node is used as identifier everywhere else. Even in the log messages. Maybe you can add it here too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point we might not know the public key of the node (at least if it's an incoming connection), this is being called before the handshake from the initConnection
method. But you're right that it's a little unusual. Maybe it should say Connected to peer [nodePubKey]
if it has a valid handshakeState and Connected pre-handshake to peer [socketAddress]
otherwise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No it is fine to leave it this way. I didn't think of inbound connections.
lib/p2p/Peer.ts
Outdated
if (this.nodePubKey === undefined) { | ||
this.logger.verbose(`Socket closed prior to handshake (${this.socketAddress.toString()})`); | ||
} else if (hadError) { | ||
this.logger.warn(`Peer ${this.nodePubKey} socket closed due to error (${this.socketAddress.toString()})`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this.socketAddress.toString()
returning the error in this case or does it get printed in a different place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah the error would get logged elsewhere, but this message is a little unclear. Maybe it should just not print the socket address if we have a nodePubKey value to print instead.
2571e58
to
fe8c5ef
Compare
I removed the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks good to me.
lib/utils/addressUtils.ts
Outdated
import assert from 'assert'; | ||
|
||
/** Helper methods for interacting with the [[Address]] type. */ | ||
export const addressUtils = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be exported as the default.
Besides that, I preferred the class implementation, as it was before, specially because toString
is called many times. In my earlier comment I was just wandering about the naming, but it wasn't an issue.
Both solutions are fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I wanted a type was for the NodeFactory
type definition plus a handful of other places where we were using host+port tuples. Using SocketAddress
wouldn't have worked I believe because it was a class with a public toString
method. I agree the current toString
usage is a bit awkward, but if it's ok with you then we can leave it.
lib/p2p/Peer.ts
Outdated
if (this.connected) { | ||
// don't log anything on close if we've never connected as the connection failure is logged elsewhere | ||
if (this.nodePubKey === undefined) { | ||
this.logger.verbose(`Socket closed prior to handshake (${addressUtils.toString(this.socketAddress)})`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be changed to info
// check that this node is not ourselves, that it has listening addresses, | ||
// and that either we haven't heard of it, or we're not ignoring known nodes and it's not banned | ||
if (node.nodePubKey !== this.handshakeData.nodePubKey && node.addresses.length > 0 && | ||
(!this.nodes.has(node.nodePubKey) || (!ignoreKnown && !this.nodes.isBanned(node.nodePubKey)))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: all conditions here are negative (including ignoreKnown
). I think that making them positive will make it easier to follow. So basically checking whether to drop the node, instead of whether to connect to it. ignoreKnown
can be turned to allowKnown
,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would that look like? I can't use a continue
statement here unless I change it from a foreach
. And fwiw if we are checking whether to skip a node, ignoreKnown
would make more sense I figure.
I know it's a pretty complex if
statement, that's why I added the comments above to try to make it more clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return
should be the same for that manner.
But you can leave it as is if it doesn't work for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right return
would work, I didn't think of that. But I think I'll leave it as is if that's OK. One of the checks does happen to be positive (node.addresses.length > 0).
* Attempt to create an outbound connection to a node using its known listening addresses. | ||
*/ | ||
private connectNode = async ({ addresses, nodePubKey }: NodeConnectionInfo) => { | ||
for (let n = 0; n < addresses.length; n += 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
forEach
instead? parallel to connectNodes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I used a regular for loop is to be able to use the break
command after the first successful connection, which I don't believe works with .forEach()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- add
nodePubKey
toxucli getinfo
output - make [nodePubKey] optional in
xucli connect
- kilrau@ubuntu:~/xud/bin$ ./xucli connect 03b46799265e53fd8255915f4f62929728f42c6144e89d82626a64ca1f09ea792e 35.236.118.88 8885
Error: 3 INVALID_ARGUMENT: nodePubKey must be specified
fe8c5ef
to
ffbe61f
Compare
OK, Resolved conflicts again and addressed some of @moshababo's comments. @kilrau Thanks for catching that bug with the cli, it's fixed now. I had to regenerate the type declarations for xudrpc and I used the new script I posted in #338. Give it a quick test again if you can. |
ebdcf8e
to
d10b05a
Compare
Had to make some changes to the sanity tests including a new test case, also fixed what I believe is a bug in that both nodes were using the same port. Travis tests pass but looks like the node isn't shutting down properly, so I'll look into that. Still good for testing and I think just needs this sanity test/shutdown thing straightened out. Sanity tests don't work for me at all when I do them locally, whether on master or this branch. I get this every time. "before all" hook:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. |
d10b05a
to
523932c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CLI connect
still has issues @sangaman 😞
~/xud/bin$ ./xucli connect 03b46799265e53fd8255915f4f62929728f42c6144e89d82626a64ca1f09ea792e 35.236.118.88 8885
{
"result": "Not connected"
}
2018-8-15 16:56:05 [P2P] warn: error while opening connection to peer 03b46799265e53fd8255915f4f62929728f42c6144e89d82626a64ca1f09ea792e: Connection timed out.
Interestingy also now it accepts to not specify nodePubKey
OR port
and still fails as timeout. Did you make one of them optional finally?
Can you provide an example of xucli connect 35.236.118.88
xucli connect <node_pub_key> <host> [port]
connect to an xu node
Options:
--help Show help [boolean]
--version Show version number [boolean]
--rpc.port, -p RPC service port [number] [default: 8886]
--rpc.host, -h RPC service hostname [string] [default: "localhost"]
--node_pub_key nodePubKey of peer to connect [string]
--host hostname or IP address [string]
--port listening port number [number] [default: "8885"]
Not enough non-option arguments: got 1, need at least 2 |
Above connection issue is fixed now. Opened separate issue to catch error states caused by corrupted/unexpected data from the db: #349 Question regarding #162 : why does
Also: why don't you query and it did go through:
Same with #177:
To be tested: order match, #271 |
523932c
to
541bd42
Compare
I haven't tested explicitly trying to connect to oneself, in my tests it looks like it connects but fails the handshake. I can put in a check up front, but I'd rather do it in a separate PR to keep this one from getting bigger than it already is. It should be low priority, you have to intentionally be trying to mess things up by commanding xud to connect to yourself. What's prevented here is connecting to yourself when other peers tell you about yourself. I fixed the builds and added more p2p sanity test cases, but I did detect a weird edge case bug I'll open an issue for later, it existed before this PR. I also fixed a bug with initialization, it was possible for the web proxy initialization to prevent xud from starting if it failed. |
lib/p2p/Peer.ts
Outdated
assert(!this.opened); | ||
this.opened = true; | ||
|
||
if (this.closed) { | ||
throw 'wtf'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good error message 🤣
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, I put this in as a sanity test for the sanity tests when I was trying to see why they'd never terminate. I'll probably change this to something a little more formal - probably just an assert like above - but it's really something that should never happen.
Agree, put the upfront check in a separte issue: #352 |
541bd42
to
14955bf
Compare
Ok last set of changes I hope, but I made it so that attempting to connect to yourself throws an error upfront before the handshake, and added a test case for that. @kilrau doing a few quick tests then this can be merged. |
This is a structural change to the p2p layer with breaking database changes. - The term to represent a known xud instance that we are not necessarily connected to is changed from "Host" to "Node" and all references have been renamed. - The unique identifier for a node used throughout the codebase is their `nodePubKey` rather than their socket address. - External addresses for incoming connections are configurable and are shared during handshake. These are persisted to the `nodes` table as a JSON string under the `addressesText` column. - On receiving NODES packets, connections are only attempted to nodes that we were not previously aware of. This also makes minor fixes and adds new test cases to the p2p sanity tests.
Removes the `SocketAddress` class to avoid confusion with the `Address` type and moves the functionality to `addressUtils` helper classes.
Fixes a bug with the xud initialization that would hang when the web proxy server fails to start listening, which happens if the rpc server is disabled. Also initializes components which don't have dependencies on each other in parallel to improve start start time.
14955bf
to
5bd11a1
Compare
Fixes #289. Fixes #271. Fixes #269. Closes #155. Implements parts of #185 and #162. Edit: Closes #177. Closes #305.
This is a structural change to the p2p layer with breaking database changes.
nodePubKey
rather than their socket address.I'm opening this PR a bit early for purposes of getting input. Todo before merging:
Hardcode the nodePubKeys of the three xud seed nodes.Edit: Done.Update README.Edit: Done.