TrustedPeers are specified in the configuration. Additional peers
can be added at runtime with Trust/Distrust functions.
Unfortunately we cannot use consensus.PeerAdd as a way to trust a peer as
cluster.PeerAdd+Join can be called by any peer and this calls
consensus.PeerAdd.
The result is consensus.PeerAdd doing a lot in Raft while consensus.Trust does
nothing, while in CRDTs consensus.Trust does something but consensus.PeerAdd
does nothing. But this is more or less consistent.
I cannot have RPCAPIs expose a SvcID() method as gorpc will warn about it not
having the right signature. So I have created an RPCServiceID() method instead.
While right now it is not allowed for the user to overwrite any entries
in the default policy from the JSON, this should be possible (and easy)
in the future.
PeerAdd called RPC endpoints for `LogMetric` and `ConnectSwarms`
remotely. However, I think similar effect can be achieved by calling
these from the Join() function locally.
In particular, ConnectSwarms was called when maybe the joining peer did not
even know about the other peers in the Cluster. Now this is delayed until some
ping metrics have come through.
I had thought of this for a very long time but there were no compelling
reasons to do it. Specifying RPC endpoint permissions becomes however
significantly nicer if each Component is a different RPC Service. This also
fixes some naming issues like having to prefix methods with the component name
to separate them from methods named in the same way in some other component
(Pin and IPFSPin).
The IPFS pin/update endpoint takes two arguments and usually
unpins the first and pins the second. It is a bit more efficient
to do it in a single operation than two separate ones.
This will make the proxy endpoint hijack pin/update requests.
First, the FROM pin is fetched from the state. If present, we
set the options (replication factors, actual allocations) from
that pin to the new one. Then we pin the TO item and proceed
to unpin the FROM item when `unpin` is not false.
We need to support path resolving, just like IPFS, therefore
it was necessary to expose IPFSResolve() via RPC.
Currently `curl -X GET http://localhost:9094/allocations` results in an
empty array, because no filter is provided. Solution to this would be
either 1) to consider filter as all if no filter is provided by the user
or 2) to make the `filter` parameter mandatory and reply with BadRequest
if no filter is provided
This commit makes the default filter as all
This adds a new "crdt" consensus component using go-ds-crdt.
This implies several refactors to fully make cluster consensus-component
independent:
* Delete mapstate and fully adopt dsstate (after people have migrated).
* Return errors from state methods rather than ignoring them.
* Add a new "datastore" modules so that we can configure datastores in the
main configuration like other components.
* Let the consensus components fully define the "state.State". Thus, they do
not receive the state, they receive the storage where we put the state (a
go-datastore).
* Allow to customize how the monitor component obtains Peers() (the current
peerset), including avoiding using the current peerset. At the moment the
crdt consensus uses the monitoring component to define the current peerset.
Therefore the monitor component cannot rely on the consensus component to
produce a peerset.
* Re-factor/re-implementation of "ipfs-cluster-service state"
operations. Includes the dissapearance of the "migrate" one.
The CRDT consensus component defines creates a crdt-datastore (with ipfs-lite)
and uses it to intitialize a dssate. Thus the crdt-store is elegantly
wrapped. Any modifications to the state get automatically replicated to other
peers. We store all the CRDT DAG blocks in the local datastore.
The consensus components only expose a ReadOnly state, as any modifications to
the shared state should happen through them.
DHT and PubSub facilities must now be created outside of Cluster and passed in
so they can be re-used by different components.