Commit Graph

30 Commits

Author SHA1 Message Date
cloudhead 59f506dbb5
radicle: Fix bug in node.db query 2023-12-19 13:26:17 +01:00
cloudhead 6f7c2dca91
node: Introduce connection penalty system
Previously, we might ban a node if we're having trouble connecting to
it, but this could be due to internet connectivity issues.

We introduce a penalty score for nodes, that increases if there are
connection issues or the node misbehaves, and decreases on successful
connections.

When connected to new nodes, we sort them so that low-penalty nodes are
attempted first.
2023-12-15 16:00:09 +01:00
cloudhead d9a84de5ee
radicle: Simple database migration system
We create a system for migrating the our databases, as well as a first
migration, for adding a `penalty` field to the `nodes` table, which we
are going to need soon, as an example.
2023-12-15 12:04:54 +01:00
cloudhead 6b04eff34c
radicle: Consolidate databases
Instead of having a routing database, and an addresses database,
consolidate that in a single database called `node.db`.

We also simplify database access, by providing a single type for opening
the database, and use traits to access the various functions.

We create a new `seed::Store` that has seed-related methods split out of
the `address::Store`.

Note that tracking is still in its own database currently, as it isn't
ephemeral state. This makes it easy to delete the new `node.db` without
risk of losing any important information.

To avoid renaming all database methods, we create a `Stores` wrapper
that allows us to access routing, addresses, seeds etc. without type
ambiguity.

This is a breaking change and requires `addresses.db` and `routing.db`
to be deleted.
2023-11-30 13:00:59 +01:00
cloudhead dfe0cb4342
cli: Polish the `rad sync status` output 2023-11-22 17:40:51 +01:00
cloudhead 358324883c
node: Announce offline ref updates
Currently, if refs are updated while the node is stopped, these refs are
not immediately announced when the node starts, due to the node being
unaware of the updates.

To remedy this, on startup, we compare the refs we have in storage with
the refs we announced to the network. Since only our own refs could have
changed while the node was stopped, this change only applies to owned
refs. If we detect that storage has changed while the node was stopped,
we create ref announcements for the updated repos and store them in our
gossip database. These announcements will be included with other
historical gossip announcements when nodes connect to us.

To keep track of what was announced, we store our local node's sync
status in the database. This is also useful when using the `rad sync status`
command, as it tells us what oid our local node is at, and whether it
is aware of our local changes yet.

In addition to this, we make a small fix: previously, inventory and ref
announcements originating from our local node were not stored in the
announcement database. We ensure that they are via the new `announce`
method.
2023-11-20 17:54:36 +01:00
cloudhead d4ec2176bb
Update Rust toolchain to 1.74 2023-11-17 16:58:24 +01:00
cloudhead d3b0483f42
cli: Implement `rad sync status` command
This command shows the sync status of a repository by consulting the
database via the node.

To make it work, we call into the address store to update the
`repo-sync-status` table when receiving ref announcements that are
relevant to us.
2023-11-17 16:56:19 +01:00
cloudhead ca557909c2
radicle: Fix some serialization issues
For some inexplicable reason, deserializing doesn't work unless we use
our custom de-serializer for `LocalTime`.
2023-11-17 16:54:27 +01:00
cloudhead aa13f57e7d
radicle: Fix issues with the address store SQL 2023-11-17 16:54:27 +01:00
cloudhead ea4104dbd7
node: Only process messages from known nodes
Previously, we would process any valid inventory or refs announcement.
This could cause problems for keeping sync statuses, as we could get
a refs announcement from a node that isn't in our database.

In practice, there is no good reason why we should receive a refs or
inventory announcement before the announcer's node announcement, unless
nodes are not following the protocol.

Implementing this change meant that many of the tests needed updating,
as it wasn't assumed that a node announcement was needed before
receiving inventories etc. from a peer.

We also had to implement a basic form of node address banning to make
the tests pass after this change.
2023-11-13 16:15:57 +01:00
cloudhead 0ae3c00cd7
Use cascading deletes for removal of node rows
Instead of manually removing all rows in the address table, use
cascading deletes.
2023-11-13 16:01:18 +01:00
cloudhead 9f45405c64
Add table and types for tracking sync status
We add the necessary database table to keep track of which node has
synced which of our repos. This will be useful for giving the user
information on the sync status of every local repository.
2023-11-13 12:03:24 +01:00
cloudhead b675185538
node: Improve control socket API
We improve the API so that error messages can be sent back and are
always expected as potential responses to commands. This means that
`CommandResult` is always the type that is sent for commands.

This includes some breaking changes, for example the default "success"
message is simply `{}` instead of `{"status":"ok"}`.
2023-11-13 11:02:45 +01:00
cloudhead f0754330c9
Update `sqlite` dependency to 0.32.0 2023-11-08 15:08:01 +01:00
cloudhead f9df360171
node: Persist historical gossip messages
Instead of storing received gossip messages in an in-memory `BTreeMap`,
we persist them to the database (`addresses.db`). There are two reasons
for this:

1. Node restarts do not wipe the state, meaning that it is much less
   likely that some gossip message will get lost before reaching all
   nodes.
2. This will allow us in the next commit to know how far behind we are
   after a restart, to be able to request the correct time range of
   gossip messages that we missed while offline.

Note that we now share the addresses.db file between two connections and
stores, which we don't do anywhere else. Having multiple connections to
the same database is fine, but the way we're having to do it is a bit
awkward. In a future patch, we could pull out the database schema from the
`address` module and rename the database to make things clearer.
2023-11-08 13:15:56 +01:00
cloudhead 8cb8398be9
Introduce `cargo-deny`
Add `deny.toml` with a few exceptions, and update certain dependencies
to get rid of duplicates.

Running `cargo deny check` will yield some warnings still, but no
errors.
2023-08-22 14:33:00 +02:00
cloudhead 14c204a11f
radicle: Fix flaky test due to randomness 2023-08-13 21:20:27 +02:00
cloudhead d973fd42f2
cli: Auto-connect on sync
This adds functionality so that on `rad sync` and `rad clone`, we
connect to known seeds if necessary, before attempting to fetch.

In passing, some related changes were made:

* The `rad sync` command's arguments were reworked:
  `--replicas <count>` can be used to specify a replica count when
    fetching
* The `rad patch` command no longer has a `--fetch` option
* It's now possible to tell the node not to automatically connect to
  peers in the background
* `AddressBook` is being used underneath `Seeds` to allow for shuffled
  iteration
2023-08-11 11:45:27 +02:00
cloudhead efb8de2728
Rename our custom `HashMap` to `RandomMap`
This makes it easier to distinguish with the stdlib.

Also, we add an env var that can control the RNG seed, for testing
purposes.
2023-08-10 16:51:02 +02:00
cloudhead e888398519
node: Populate address book with bootstrap nodes
As a starting point, we populate the address book (if empty) with some
bootstrap nodes which are trusted.

To prevent these nodes being connected to during tests (including e2e
tests), we create a new constructor for `Config` that is used in tests.

Note that a `cfg(test)` check is not enough given that e2e tests don't
have that set.
2023-08-09 12:39:33 +02:00
Alexis Sellier b953e9f6b5
node: Use `camelCase` for control socket data
It's easier if we use camel-case everywhere, because some types may be
used on the web as well as on the control socket. This way, all
json-encoded data looks the same.
2023-08-01 15:48:44 +02:00
Alexis Sellier 8a3133e137
node: Include addresses in `Command::Seeds` result
This will allow the CLI to connect to seeds on the go.

We also do some refactoring of some of the code involved in fulfilling
the `Seeds` command.
2023-08-01 15:48:44 +02:00
Alexis Sellier 85b092872d
node: Support DNS address types at the wire level 2023-08-01 14:55:20 +02:00
Alexis Sellier eb701be033
node: Make node aliases required
This is a fairly substantial change, which adds a new configuration file
to the user's `$RAD_HOME` that includes node configuration, including
the alias, and also makes node aliases required.

When running `rad auth`, the user is now prompted for an alias, which
defaults to `$USER`.

When running `rad self`, the alias is now shown.

If the user runs radicle without a config file, the defaults are loaded,
and `$USER` is used as the alias.
2023-07-11 18:08:59 +02:00
Alexis Sellier 5502676aa7
Fixes and improvements to alias handling
* Return the correct alias from a node announcement, stripping '\0'
  bytes.
* Accept `AliasStore` types as references and as owned.
* Store a `null` in the database if the alias received is empty.
2023-06-13 11:09:42 +02:00
Alexis Sellier ff7338de17
node: Always send node announcement on handshake
Previously, we only sent the announcement when there were external
addresses. But it contains other information like the node alias,
therefore we always send it.

Since the proof-of-work can be expensive to compute everytime, we add
the ability to load the local node announcement from the file system.

We also change the proof-of-work parameters so that they are relaxed
when running in debug mode, instead of when running tests.

Finally, we remove the boolean validation of the PoW. Instead, we store
the work per-node, in the database, to be used in the future in case of
DoS attacks or network congestion.
2023-06-07 11:39:23 +02:00
xphoniex 13bea902b2
radicle: Create `Aliases` and use it in `httpd`
Signed-off-by: xphoniex <dj.2dixx@gmail.com>
2023-06-02 14:50:49 +02:00
xphoniex 0cae3c0967
radicle: Implement `AliasStore` for address `Book` 2023-06-02 14:49:30 +02:00
xphoniex f526465f1b
radicle: Make addresses.db accessible from profile
Signed-off-by: xphoniex <dj.2dixx@gmail.com>
2023-06-02 14:49:20 +02:00