@@ -18,16 +18,17 @@ protocol to share dispatched redux actions among peers, and eventually agree on
18
18
their order in time. As actions from the past arrive, we replay history as if
19
19
they had always existed.
20
20
21
- A sample "server" peer is included, which might sync changes to a database,
22
- write a persistent log, or manage system/world/NPC actors.
21
+ A sample "server" peer is included, which might sync state changes to a
22
+ database, write a persistent log, or manage system/world/NPC actors.
23
23
24
- While it works great in a client-server set up, you could upgrade/downgrade to
25
- peer-to-peer connections, or go offline, and changes sync when you next connect.
24
+ While it works great in a traditional client-server set up, you can flexibly
25
+ upgrade/downgrade to peer-to-peer connections, go offline for minutes or days,
26
+ and changes will sync when you next connect to another scuttlebutt instance.
26
27
27
- Note, scuttlebutt does not make any guarantees of security or identity. Peer
28
- ` Bob ` is free to lie to ` Jane ` about ` Amy ` 's actions. A client-server layout can
29
- mitigate this risk, and WebSockets over SSL mitigates MITM replacement, but as
30
- the project matures this will be brought into consideration .
28
+ Note, by default, scuttlebutt itself does not make any guarantees of security or
29
+ identity: peer ` Bob ` is able to lie to ` Jane ` about ` Amy ` 's actions. Security
30
+ guarantees can added using the
31
+ [ ` signAsync ` and ` verifyAsync ` ] ( #signasync--verifyasync )] dispatcher options .
31
32
32
33
For more, read the
33
34
[ Scuttlebutt paper] ( http://www.cs.cornell.edu/home/rvr/papers/flowgossip.pdf ) .
@@ -55,15 +56,14 @@ export default (initialState) => {
55
56
uri: ' http://localhost:3000' ,
56
57
}))
57
58
}
58
-
59
59
```
60
60
61
61
It wraps your store's root reducer (to store history), ` getState ` (to return the
62
62
current state in history) and ` dispatch ` (to connect to peers).
63
63
64
- If you're using the redux devtools enhancer, it must come * after* the redux-
65
- scuttlebutt enhancer (or scuttlebutt will try to emit ` PERFORM_ACTION ` across
66
- the network)
64
+ If you're using the redux dev-tools enhancer, it must come * after* the redux-
65
+ scuttlebutt enhancer (or scuttlebutt will emit ` PERFORM_ACTION ` actions over the
66
+ network).
67
67
68
68
## options
69
69
@@ -115,33 +115,29 @@ scuttlebutt({
115
115
})
116
116
```
117
117
118
- ### verifyAsync & signAsync
118
+ ### signAsync & verifyAsync
119
+
120
+ The dispatcher options ` signAsync ` and ` verifyAsync ` allows you to add arbitrary
121
+ metadata to actions as they are dispatched, and filter remote actions which are
122
+ received from peers. This means you can validate any action against itself or
123
+ the redux state, other actions in history, a cryptographic signature, rate
124
+ limit, or any arbitrary rule.
119
125
120
- The dispatcher option ` verifyAsync ` allows you to filter remote actions
121
- dispatched or gossiped about through scuttlebutt. You could validate an action's
122
- contents against a cryptographic signature, or rate limit, or an arbitrary rule:
126
+ For security, you can use
127
+ [ redux-signatures] ( https://github.com/grrowl/redux-signatures ) to add Ed25519
128
+ signatures to your actions. This could be used to
129
+ verify authors in a peering or mesh structure.
123
130
124
131
``` js
125
- import { UPDATE_ACTION } from ' redux-scuttlebutt'
126
-
127
- function verifyAsync (callback , action , getStateHistory ) {
128
- const history = getStateHistory (),
129
- prevUpdate = history[history .length - 1 ],
130
- prevAction = prevUpdate && prevUpdate[UPDATE_ACTION ]
131
-
132
- if (
133
- // if this message doesn't include an e
134
- action && action .payload
135
- && action .payload .indexOf (' e' ) === - 1
136
- // and the previously message didn't include an e
137
- && prevAction && prevAction && prevAction .payload
138
- && prevAction .payload .indexOf (' e' ) === - 1
139
- ) {
140
- callback (false )
141
- } else {
142
- callback (true )
143
- }
144
- }
132
+ import { Ed25519 , verifyAction , signAction } from ' redux-signatures'
133
+
134
+ const identity = new Ed25519 ()
135
+
136
+ scuttlebutt ({
137
+ uri: ' http://localhost:3000' ,
138
+ signAsync: signAction .bind (this , identity),
139
+ verifyAsync: verifyAction .bind (this , identity),
140
+ }))
145
141
```
146
142
147
143
The ` getStateHistory ` parameter returns an array of the form
@@ -177,11 +173,6 @@ strategies may be,
177
173
178
174
Examples are found under ` examples/ ` .
179
175
180
- <!--
181
- You may have to `npm link` your redux-scuttlebutt directory and `npm link redux-
182
- scuttlebutt` your example project directory during development.
183
- -->
184
-
185
176
* ` counter ` :
186
177
[ redux counter example] ( https://github.com/reactjs/redux/tree/master/examples/counter )
187
178
with the addition of redux-scuttlebutt.
@@ -197,16 +188,27 @@ scuttlebutt` your example project directory during development.
197
188
tradeoffs, which we don't want to bake into the library itself.
198
189
* our recommendation is to implement what's right for your implementation in
199
190
userland.
200
- * i've released an example of message signing with ed25519 signatures and
191
+ * have released an example of message signing with ed25519 signatures and
201
192
asyncronous message validation
202
193
[ in this gist] ( https://gist.github.com/grrowl/ca94e47a6da2062e9bd6dad211588597 ) .
203
- * some comments on our underlying ` scuttlebutt ` implementation
194
+ * released [ redux-signatures] ( https://github.com/grrowl/redux-signatures )
195
+ which plugs directly into the dispatcher.
196
+ * Allows flexible implementation, e.g. in a client-server topology you may
197
+ only want to use ` sign ` on the client and ` verify ` on the server only.
198
+ This avoids running the most processor intensive part on the clients with
199
+ no loss of security.
200
+ * underlying ` scuttlebutt ` implementation
201
+ * currently depends on our
202
+ [ own scuttlebutt fork] ( https://github.com/grrowl/scuttlebutt#logical-timestamps ) ,
203
+ not yet published to npm, I'm not sure if dominictarr wants to accept these
204
+ changes upstream.
205
+ * should probably republish as ` scuttlebutt-logical `
204
206
* add a ` @@scuttlebutt/COMPACTION ` action
205
- * reducers would recieve the whole history array as ` state `
207
+ * reducers would receive the whole history array as ` state `
206
208
* enables removing multiple actions from history which are inconsequential —
207
209
such as multiple "SET_VALUE" actions, when only the last one applies.
208
210
* also enables forgetting, and therefore not replaying to other clients,
209
- actions after a certain threshold
211
+ actions after a certain threshold.
210
212
* implement CRDT helpers for reducers to easily implement complex shared data
211
213
types.
212
214
* tests
@@ -215,6 +217,9 @@ scuttlebutt` your example project directory during development.
215
217
* ensure API
216
218
* allow pluggable socket library/transport
217
219
* more example applications! something real-time, event driven.
220
+ * WebRTC support
221
+ * Genericize server into websockets and webrtc versions
222
+ * Write client modules to support either
218
223
219
224
## contributions
220
225
0 commit comments