Circuit Abandon
Summary
This document presents the design for abandoning a circuit. A node’s
administrator may choose to abandon a circuit, removing the circuit’s
networking capability from that node’s perspective, without validation from
other circuit members. This retains the circuit state for all nodes as well as
any Splinter service data. It does update the circuit state for the abandoning
node to show the Abandoned
status of the circuit, however, and removes the
circuit’s networking. Circuits may also have a status of Active
and
Disbanded
. Only Active
circuits are able to be abandoned. If circuit
members attempt to reach the node that abandoned the circuit, via the circuit
that was abandoned, the request will fail as that circuit will no longer be
able to route the message accordingly. The abandon functionality enables
individual circuit members to leave a circuit if they so choose.
The alternative to abandoning a circuit is disbanding. Disbanding a circuit is considered a safer alternative to abandoning a circuit, as it performs relatively the same function to remove a circuit’s networking capability, but the process includes all circuit members. The Circuit Disband feature document contains more information on this alternative approach.
Guide-level explanation
Abandoning a circuit
Abandoning a circuit will remove a circuit’s networking capabilities for the requesting node and disables other members from reaching the node via the circuit that was abandoned. This request is validated by the admin service using the following criteria:
- The circuit to be abandoned exists and has a
circuit_status
ofActive
- The requester has the correct permissions for the node the circuit is being abandoned on
- The specified circuit in the request has a
circuit_version
of at least 2
If the request to abandon a circuit passes this validation, the node’s admin
service will update the circuit definition and stop any of the node’s services
running on the circuit. In terms of the circuit state update, the circuit
stored by the abandoning node is updated to show the Abandoned
circuit_status
. As this request does not require validation from other
circuit members, this operation’s changes are only local to the requesting node.
All other members of the circuit, if multiple peers remain, are able to communicate over the circuit. However, no members of the circuit will be able to communicate, via messages, over the circuit to the abandoning node.
After a circuit has been abandoned it is then able to be purged. This means all state associated with the abandoned circuit will be removed. Further information on the purge functionality may be found in the Circuit Purge feature document.
Reference-level explanation
CircuitAbandon
To abandon a circuit, first a CircuitAbandon
message must be created. The
definition of this protobuf message follows:
message CircuitAbandon {
// The unique circuit name
string circuit_id = 1;
}
This message is then wrapped in a CircuitManagementPayload
before being
submitted to the admin service. This payload would appear as follows:
message CircuitManagementPayload {
header =
Header {
action = CIRCUIT_ABANDON;
requester = <Bytes of the requester’s public key>;
payload_sha512 = <Bytes of the hash of the payload’s action>;
requester_node_id = <Node ID of the requester submitting the payload>;
}
signature = <Signature of the header included in the request>;
circuit_abandon = <`CircuitAbandon` with the circuit ID of the circuit to be abandoned>;
}
This message is then submitted to the admin service where it is validated using
the criteria explained previously. If the abandon request is successfully
validated, the admin service proceeds by disabling the circuit from the
abandoning node’s perspective. This includes updating the circuit state to the
same information stored in the previously active circuit, but with the
circuit_status
of Abandoned
. Splinter services used by the abandoning node
will also be stopped using the admin service’s ServiceOrchestrator
.
Furthermore, the abandoning node’s admin service will remove any peer
references associated with the circuit and will remove the circuit from that
node’s RoutingTable
. This essentially cuts off any communication via the
circuit from the abandoned node.
Drawbacks
As the abandon action is only local to the requesting node, this essentially ‘breaks’ the circuits from the other members’ perspectives. Meaning, consensus cannot be reached on the circuit, as the abandoning node will not receive any communications via the abandoned circuit. This will require updating how and when peer connections are created, updated, and destroyed to keep up with the ability of nodes to remove these connections.
Prior art
Circuit deletion has not been implemented in Splinter prior to this design.
Unresolved questions
- When a circuit member attempts to reach the member who has abandoned the circuit, what component would be able to communicate that the circuit has been abandoned?
- Should the admin service attempt to handle circuits that have been abandoned by another circuit member? How would this be handled beyond the current behavior of simply logging that the circuit has been abandoned?