Skip to content
This repository was archived by the owner on Feb 1, 2024. It is now read-only.

Commit 9dacf81

Browse files
RFC for adding peers in runtime
Signed-off-by: Yevhenii Babichenko <eugene@remme.io>
1 parent 7822584 commit 9dacf81

File tree

1 file changed

+173
-0
lines changed

1 file changed

+173
-0
lines changed

text/0000-add-peers-in-runtime.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
- Feature Name: `add_peers_in_runtime`
2+
- Start Date: 2018-11-12
3+
- RFC PR: (leave this empty)
4+
- Sawtooth Issue: (leave this empty)
5+
6+
# Summary
7+
[summary]: #summary
8+
This RFC proposes to implement the possibility to add new peers in runtime
9+
(through the component validator endpoint) when a node is working in the
10+
`static` peering mode. Along with that it also adds the corresponding extensions
11+
to the off-chain permissioning model.
12+
13+
# Motivation
14+
[motivation]: #motivation
15+
16+
When an administrator adds a new node to an existing Sawtooth network he/she has
17+
to restart a node with new peering settings. This makes any automation
18+
significantly harder to write than if we had the possibility to add peers in the
19+
runtime and also decreases the uptime.
20+
21+
To resolve this problem our team proposes to add a method to add new peers to a
22+
running node.
23+
24+
An example use case is using Sawtooth along with a service discovery system like
25+
[Consul](https://www.consul.io):
26+
27+
- A Consul node is set up along with the Sawtooth node;
28+
- A middleware continuously fetches the changes of the peer list from the
29+
Consul node;
30+
- The middleware adds peers to the Sawtooth node via the validator component
31+
endpoint.
32+
33+
# Guide-level explanation
34+
[guide-level-explanation]: #guide-level-explanation
35+
36+
When an administrator adds new peers to the network you very likely want to
37+
add them without restarting the validator with a newer `--peers` parameter
38+
value. To add a new peer you can send the `ClientAddPeersRequest` to the
39+
`component` endpoint of your Sawtooth validator.
40+
41+
The Protocol Buffers definition for this message is the following:
42+
43+
```protobuf
44+
message ClientAddPeersRequest {
45+
repeated string peers = 1;
46+
}
47+
```
48+
49+
Simple Python example using `sawtooth_sdk.messaging.stream`:
50+
51+
```python
52+
new_peers = ['tcp://192.168.0.100:8008', 'tcp://192.168.0.200:8008']
53+
add_peers_request = ClientAddPeersRequest(new_peers=new_peers)
54+
future = stream.send(Message.CLIENT_ADD_PEERS_REQUEST,
55+
add_peers_request.SerializeToString())
56+
response_serialized = future.result().content
57+
response = ClientAddPeersResponse()
58+
response.ParseFromString(response_serialized)
59+
```
60+
61+
The response Protocol Buffers definition is the following:
62+
63+
```protobuf
64+
message ClientAddPeersResponse {
65+
enum Status {
66+
STATUS_UNSET = 0;
67+
OK = 1;
68+
INTERNAL_ERROR = 2;
69+
// One or more of peer URIs were malformed. List of malformed URIs is in
70+
// the `invalid_uris` field of this response.
71+
INVALID_PEER_URI = 3;
72+
MAXIMUM_PEERS_CONNECTIVITY_REACHED = 4;
73+
}
74+
Status status = 1;
75+
repeated string invalid_uris = 2;
76+
}
77+
```
78+
79+
# Reference-level explanation
80+
[reference-level-explanation]: #reference-level-explanation
81+
82+
## Protocol Buffers definitions
83+
[protobuf]: #protobuf
84+
85+
I propose to add them to `protos/client_peers.proto`:
86+
87+
```protobuf
88+
message ClientAddPeersRequest {
89+
repeated string peers = 1;
90+
}
91+
92+
message ClientAddPeersResponse {
93+
enum Status {
94+
STATUS_UNSET = 0;
95+
OK = 1;
96+
INTERNAL_ERROR = 2;
97+
// One or more of peer URIs were malformed. List of malformed URIs is in
98+
// the `invalid_uris` field of this response.
99+
INVALID_PEER_URI = 3;
100+
MAXIMUM_PEERS_CONNECTIVITY_REACHED = 4;
101+
}
102+
Status status = 1;
103+
repeated string invalid_uris = 2;
104+
}
105+
```
106+
107+
The rationale behind the `invalid_uris` is to be more precise about what is
108+
wrong and to ease the debugging process for developers.
109+
110+
## How are the requests processed by the validator
111+
[request-processing]: #request-processing
112+
113+
The requests are received on the `component` endpoint. When the validator
114+
receives a new request for adding peers it:
115+
116+
- Validates the format of peer URIs which has to be
117+
`tcp://IP_ADDRESS:PORT_NUMBER`
118+
- If the validation was successful then the validator updates its peer list and
119+
immediately returns the `OK` response. The new peers are connected _after_
120+
that.
121+
122+
Edge cases:
123+
124+
- The peer address format was wrong in one or more of the provided peers. If
125+
that happens then the request fails without adding any new peers to the peers
126+
list and returns the `INVALID_PEER_URI` status along with the list of faulty
127+
peer URIs.
128+
- If the `--maximum-peer-connectivity` parameter was provided to the validator
129+
then the validator checks if it has reached the maximum peer connectivity and
130+
fails with an error if so. The validator also fails if it cannot add _all_ of
131+
the peers provided in a request without breaking the provided
132+
`maximum-peer-connectivity`.
133+
134+
# Drawbacks
135+
[drawbacks]: #drawbacks
136+
137+
- The proposed solution does not provide any information on the status of new
138+
peers. It just returns immediately if a request does not break the conditions
139+
specified in the previous chapter.
140+
- It does not specify any connection retry policies leaving it to the existing
141+
peering implementation.
142+
143+
# Rationale and alternatives
144+
[alternatives]: #alternatives
145+
146+
Alternatives were not considered and judging from multiple examples this is the
147+
state-of-the-art solution.
148+
149+
# Prior art
150+
[prior-art]: #prior-art
151+
152+
- [`addnode` in Bitcoin JSON RPC](https://bitcoincore.org/en/doc/0.16.0/rpc/network/addnode/)
153+
- [`admin_addPeer` in Ethereum management API](https://github.com/ethereum/go-ethereum/wiki/Management-APIs#admin_addpeer)
154+
155+
Those two allow adding new peers in their platforms. Interesting points:
156+
157+
- Ethereum can return the connection status;
158+
- Bitcoin allows specifying the connection retry policy.
159+
160+
# Unresolved questions
161+
[unresolved]: #unresolved-questions
162+
163+
- During the pre-RFC discussion on the #sawtooth-core-dev channel, there was no
164+
final solution on "should it be included to the REST API or no?"
165+
- In the same discussion, there was a proposition to resolve security issues by
166+
using this feature along with the permissioning module. If we do not add this
167+
feature to the REST API and hence to the administrative utilities then I do
168+
not see any point in permissioning because the described feature remains an
169+
internal interface of the application. Even if we do then we can restrict the
170+
access to that feature by using a proxy as suggested in the documentation.
171+
- Should the system notify its user about the statuses of new connections or
172+
leave the status check to the end user?
173+
- Should our team include the integration example of this solution for Consul?

0 commit comments

Comments
 (0)