-
Notifications
You must be signed in to change notification settings - Fork 4
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
Supporting trusted seed nodes (nodes
domain refactoring, static sources for seed nodes)
#289
Conversation
In the process of refactoring const leastActive = bucketEntries.reduce((prev, curr) => {
return prev[1].lastUpdated < curr[1].lastUpdated ? prev : curr;
}); was saying that
What I realised was that it was actually doing a Therefore, an easy fix: const leastActive = bucketEntries.reduce((prev, curr) => {
return new Date(prev[1].lastUpdated) < new Date(curr[1].lastUpdated) ? prev : curr;
}); I've also added a test for this scenario in 747a009 |
nodes
, input sources,nodes
domain refactoring, static sources for seed nodes)
To provide support for both hostnames and IP addresses in our Kademlia system, I'm hoping to make to make this as simple as possible by simply extending the type NodeAddress = {
ip: Host;
port: Port;
}; to the following: type NodeAddress = {
host: IPAddress | Hostname;
port: Port;
}; where both However, thinking about this some more, this won't work. The Perhaps instead of this then, we'll need a function to parse the |
If you change That way you know that See: https://en.wikipedia.org/wiki/Hostname it's always DNS. |
Yeah that seems fine, but I don't think changing the types actually resolves the problem of supporting hostnames, because they're just stored as strings in leveldb. So whenever we retrieve from the database, there's no type information to discern whether it's an IP address or a hostname. So I'm thinking we'll need a parser to check what it is? Is there a simpler solution? |
If you have a function that can take In fact I reckon there should be only 1 or 2 places where |
See: https://nodejs.org/api/net.html#netisipinput for checking if it is an IP. All other things are going to be hostnames. I think we do use this a bit?
|
BTW this requires fixing: const [client,] = await Promise.all([
GRPCClientAgent.createGRPCClientAgent({
nodeId: this.targetNodeId,
host: this.ingressHost,
port: this.ingressPort,
proxyConfig: this.proxyConfig,
logger: this.logger.getChild(GRPCClientAgent.name),
}),
Array.from(brokerConnections, ([_, conn]) =>
conn.sendHolePunchMessage(
this.keyManager.getNodeId(),
this.targetNodeId,
egressAddress,
signature,
),
),
]); It nests the promise array: You should be spreading it. Use Right now this is promise leak. |
There's a few instances where
Furthermore, as far as I can tell, the only place we will need to resolve a hostname is when creating a connection to it (or, more generally, when we need to actually perform any network-related actions to the host). As such:
Therefore, I see the best solution as only resolving the hostname to an IP when it's required for the networking work. This would mean that it is resolved internally, as opposed to on the boundary. It seems that in all other places, it's preferable to be preserving it as a EDIT: There was some discussion in our sprint meeting today (15/11/2021) about whether this might be the best approach. We need to think about whether there are any implications of allowing hostnames for any arbitrary keynode. (Right now, we treat the seed nodes as an arbitrary keynode, and as such, a Right now, the expectation is that only seed nodes would be utilising a hostname. Are there consequences for potentially allowing this for regular keynodes? |
It's quite useful to have extended the type NodeAddress = {
ip: Host | Hostname;
port: Port;
}; for type safety. That is, when retrieving from the database, or getting some |
Can that be? type NodeAddress = {
host: Host | Hostname;
port: Port;
}; |
Yeah, that's easy enough, I'll change it. EDIT: This is done: 491bcd8 |
ff45e0c
to
d9ccb8e
Compare
I've rebased this on master now, so it includes the changes from #284. |
|
I've been having some troubles with We expect that a user can supply multiple seed nodes on start. For example: This means that, like the However, I'm noticing some issues with the usage of |
Specifically documenting the issue: For the following in function parseSeedNodes(rawSeedNode: string): NodeMapping {
const idHostPort = rawSeedNode.split(/[@:]/);
if (idHostPort.length != 3) {
throw new commander.InvalidOptionArgumentError(`${rawSeedNode} is not of format 'nodeId@host:port'`)
}
if (!nodesUtils.isNodeId(idHostPort[0])) {
throw new commander.InvalidOptionArgumentError(`${idHostPort[0]} is not a valid node ID`);
}
if (!networkUtils.isValidHostname(idHostPort[1])) {
throw new commander.InvalidOptionArgumentError(`${idHostPort[1]} is not a valid hostname`);
}
const port = parseNumber(idHostPort[2]);
const seedNode: NodeMapping = {
id: idHostPort[0] as NodeId,
host: idHostPort[1] as Host | Hostname,
port: port as Port,
};
return seedNode;
// remove curr prev, just try curr
}
const seedNodes = new commander.Option(
'-sn, --seed-node [nodeId@host:port...]',
'Seed Node address mapping',
)
.argParser(parseSeedNodes)
.env('PK_SEED_NODES') // TODO: need to figure out how to parse env
.default(getConfigSeedNodes()); And the following test: describe('Providing seed nodes on start', () => {
const seedNode1Id = makeNodeId('vi3et1hrpv2m2lrplcm7cu913kr45v51cak54vm68anlbvuf83ra0');
const seedNode1Host = 'testnet.polykey.io' as Hostname;
const seedNode1Port = 1314 as Port;
const seedNode2Id = makeNodeId('v359vgrgmqf1r5g4fvisiddjknjko6bmm4qv7646jr7fi9enbfuug');
const seedNode2Host = 'testnet.polykey.io' as Hostname;
const seedNode2Port = 1315 as Port;
test.only('multiple -sn CLI arguments', async () => {
const result = await testUtils.pk([
'agent',
'start',
'-np',
foregroundNodePath,
'--password-file',
passwordFile,
'-sn',
`${seedNode1Id}@${seedNode1Host}:${seedNode1Port}`,
`${seedNode2Id}@${seedNode2Host}:${seedNode2Port}`,
]); Logging
i.e. only one of the seed nodes present when using |
I'm having some problems with the session token seemingly not being created on
When attempting to create and start
I've traced this to Given that the session authentication has changed a bit in the Gitlab MR, I'm considering waiting to rebase once it's merged such that these problems might just resolve themselves. Some discussion of changes from here onwards: https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/213#note_737728551 |
d44346f
to
3a4edfa
Compare
I've squashed the commits of this PR down. Given that I'd initially branched from #283, I've squashed those commits from #283 down to a single, separate commit d4fde43. There's some commits I'm missing from #283, but I expect that this will be resolved after #283 is merged into master, and I make another rebase on master after that. |
Lots of merge conflicts to resolve after rebasing on master! Spending some time on it. |
3a4edfa
to
c5f29cf
Compare
Current status with this PR:
I know there's been some refactoring in #283, so depending on merge order, it may make sense for me to rebase on #283 again before merging. |
I was having some initial issues with setting up the required tests here: #289 (comment) Given that the session refactoring has changed this a fair bit, if I don't encounter these issues anymore, then I can hopefully get these tests completed by today. After that, this PR will be ready for review and merge. |
Given that I've been working on the roadmap and issue planning this afternoon, haven't had a chance to look at the bin tests today. Will be picking them up tomorrow morning. |
83cffbe
to
28f1582
Compare
Rebased on master |
Will need to look at:
|
Assigned to @tegefaulkes to help finish this off. |
Only 2 tests are failing now.
Looking into them now. |
|
1. Adding support for hostnames 2. Adding parsers for seed node sources 3. --seed-nodes option added to pk agent start 4. Separating NodeGraph db sync from NodeGraph.start 5. Adding Fixing timeouts for connections. 6. Separating seed node connection establishment from NodeManager.start, and adding to PolykeyAgent.start instead (dependency on ForwardProxy being started) 7. Re-adding the seed nodes into config.ts and setting PK_SEED_NODES to be empty by default (for CLI testing to connect to 0 seed nodes by default)
Not yet. We will address in CI/CD PR with overall testing overhaul. |
984e701
to
c896b81
Compare
Fixed the two above issues, squashed and linted. |
CI/CD is running on this now, if that passes then we can merge this. |
Won't wait for the CI/CD. I'm expecting failures that will be fixed by the #231 PR. |
Description
Supporting trusted seed nodes configuration.
Issues Fixed
src/config.ts
for bootstrapping the P2P network #269Tasks
nodes
domain:broker
intoseed
nodesbrokerNodeConnections
- the seed nodes should be treated as regular nodes, that get added to theNodeGraph
(Kademlia system)NodeAddress.ip
toNodeAddress.host
resolveHost
function to resolve a hostname into an IP address (Host
type)resolveHost
calls are required, and add them inNodeMapping
:NodeId -> NodeAddress
- i.e.NodeBucket
without thelastUpdated
field)nodeId@host:port
structureresolve issue with variadic options andno longer a problem - see Embed Trusted Default Seed Nodes intoargParser
UsingOption.parseArgs
with variadic and default options tj/commander.js#1641src/config.ts
for bootstrapping the P2P network #269 (comment)PK_SEED_NODES
.env
with this parsing logic (instead of just a straight read from environment)src/config.ts
config.ts
POJO structurePK_SEED_NODES
environment variable (and takes precedence oversrc/config.ts
)PK_SEED_NODES
environment variable (and takes precedence oversrc/config.ts
)src/config.ts
src/config.ts
src/config.ts
- should only take CLI argumentssrc/config.ts
with<seed-nodes>
flag - should take CLI arguments as well assrc/config.ts
src/config.ts
- should only take CLI argumentssrc/config.ts
and<seed-nodes>
flag - should take all4. Resolve propagation of- will now be handled in #225NodeConnection
errors (from networking domain) - see #224Final checklist