experimental-features.md 17.5 KB
Newer Older
1 2 3 4
# Experimental features of go-ipfs

This document contains a list of experimental features in go-ipfs.
These features, commands, and APIs aren't mature, and you shouldn't rely on them.
Łukasz Magiera's avatar
Łukasz Magiera committed
5 6 7
Once they reach maturity, there's going to be mention in the changelog and
release posts. If they don't reach maturity, the same applies, and their code is
removed.
8 9 10

Subscribe to https://github.com/ipfs/go-ipfs/issues/3397 to get updates.

Łukasz Magiera's avatar
Łukasz Magiera committed
11 12 13
When you add a new experimental feature to go-ipfs, or change an experimental
feature, you MUST please make a PR updating this document, and link the PR in
the above issue.
14 15 16 17 18 19

- [ipfs pubsub](#ipfs-pubsub)
- [Client mode DHT routing](#client-mode-dht-routing)
- [go-multiplex stream muxer](#go-multiplex-stream-muxer)
- [Raw leaves for unixfs files](#raw-leaves-for-unixfs-files)
- [ipfs filestore](#ipfs-filestore)
20
- [ipfs urlstore](#ipfs-urlstore)
21
- [BadgerDB datastore](#badger-datastore)
22 23
- [Private Networks](#private-networks)
- [ipfs p2p](#ipfs-p2p)
Dr Ian Preston's avatar
Dr Ian Preston committed
24
- [p2p http proxy](#p2p-http-proxy)
25
- [Circuit Relay](#circuit-relay)
26
- [Plugins](#plugins)
Tylar's avatar
Tylar committed
27
- [Directory Sharding / HAMT](#directory-sharding--hamt)
28
- [IPNS PubSub](#ipns-pubsub)
29
- [QUIC](#quic)
vyzo's avatar
vyzo committed
30
- [AutoRelay](#autorelay)
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

---

## ipfs pubsub

### State

experimental, default-disabled.

### In Version

0.4.5

### How to enable

Łukasz Magiera's avatar
Łukasz Magiera committed
46 47
run your daemon with the `--enable-pubsub-experiment` flag. Then use the
`ipfs pubsub` commands.
48

49 50
### gossipsub

vyzo's avatar
vyzo committed
51 52 53 54 55 56
Gossipsub is a new, experimental routing protocol for pubsub that
should waste less bandwidth than floodsub, the current pubsub
protocol. It's backwards compatible with floodsub so enabling this
feature shouldn't break compatibility with existing IPFS nodes.

You can enable gossipsub via configuration:
57 58
`ipfs config Pubsub.Router gossipsub`

Steven Allen's avatar
Steven Allen committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
### Message Signing

As of 0.4.18, go-ipfs signs all pubsub messages by default. For now, it doesn't
*reject* unsigned messages but it will in the future.

You can turn off message signing (not recommended unless you're using a private
network) by running:
`ipfs config Pubsub.DisableSigning true`

You can turn on strict signature verification (require that all messages be
signed) by running:
`ipfs config Pubsub.StrictSignatureVerification true`

(this last option will be set to true by default and eventually removed entirely)

74 75 76 77 78 79 80 81
### Road to being a real feature
- [ ] Needs more people to use and report on how well it works
- [ ] Needs authenticated modes to be implemented
- [ ] needs performance analyses to be done

---

## Client mode DHT routing
Łukasz Magiera's avatar
Łukasz Magiera committed
82
Allows the dht to be run in a mode that doesn't serve requests to the network,
Łukasz Magiera's avatar
Łukasz Magiera committed
83
saving bandwidth.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

### State
experimental.

### In Version
0.4.5

### How to enable
run your daemon with the `--routing=dhtclient` flag.

### Road to being a real feature
- [ ] Needs more people to use and report on how well it works.
- [ ] Needs analysis of effect it has on the network as a whole.

---

## go-multiplex stream muxer
Łukasz Magiera's avatar
Łukasz Magiera committed
101 102 103 104
Adds support for using the go-multiplex stream muxer alongside (or instead of)
yamux and spdy. This multiplexer is far simpler, and uses less memory and
bandwidth than the others, but is lacking on congestion control and backpressure
logic. It is available to try out and experiment with.
105 106 107 108 109 110 111 112 113 114

### State
Experimental

### In Version
0.4.5

### How to enable
run your daemon with `--enable-mplex-experiment`

Łukasz Magiera's avatar
Łukasz Magiera committed
115 116
To make it the default stream muxer, set the environment variable
`LIBP2P_MUX_PREFS` as follows:
117 118 119 120
```
export LIBP2P_MUX_PREFS="/mplex/6.7.0 /yamux/1.0.0 /spdy/3.1.0"
```

Łukasz Magiera's avatar
Łukasz Magiera committed
121 122
To check which stream muxer is being used between any two given peers, check the
json output of the `ipfs swarm peers` command, you'll see something like this:
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
```
$ ipfs swarm peers -v --enc=json | jq .
{
  "Peers": [
    {
      "Addr": "/ip4/104.131.131.82/tcp/4001",
      "Peer": "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
      "Latency": "46.032624ms",
      "Muxer": "*peerstream_multiplex.conn",
      "Streams": [
        {
          "Protocol": "/ipfs/bitswap/1.1.0"
        },
        {
          "Protocol": "/ipfs/kad/1.0.0"
        },
        {
          "Protocol": "/ipfs/kad/1.0.0"
        }
      ]
    },
    {
...
```

### Road to being a real feature
Łukasz Magiera's avatar
Łukasz Magiera committed
149 150
- [ ] Significant real world testing and performance metrics across a wide
      variety of workloads showing that it works well.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185

---

## Raw Leaves for unixfs files
Allows files to be added with no formatting in the leaf nodes of the graph.

### State
experimental.

### In Version
master, 0.4.5

### How to enable
Use `--raw-leaves` flag when calling `ipfs add`.

### Road to being a real feature
- [ ] Needs more people to use and report on how well it works.

---

## ipfs filestore
Allows files to be added without duplicating the space they take up on disk.

### State
experimental.

### In Version
master, 0.4.7

### How to enable
Modify your ipfs config:
```
ipfs config --json Experimental.FilestoreEnabled true
```

Bamvor Zhang's avatar
Bamvor Zhang committed
186 187 188 189
Then restart your IPFS node to reload your config.

Finally, when adding files with ipfs add, pass the --nocopy flag to use the
filestore instead of copying the files into your local IPFS repo.
190 191 192 193 194 195 196 197 198

### Road to being a real feature
- [ ] Needs more people to use and report on how well it works.
- [ ] Need to address error states and failure conditions
- [ ] Need to write docs on usage, advantages, disadvantages
- [ ] Need to merge utility commands to aid in maintenance and repair of filestore

---

199 200 201 202 203 204 205
## ipfs urlstore
Allows ipfs to retrieve blocks contents via a url instead of storing it in the datastore

### State
experimental.

### In Version
206
master, v0.4.17
207 208 209 210 211 212 213

### How to enable
Modify your ipfs config:
```
ipfs config --json Experimental.UrlstoreEnabled true
```

214 215
And then add a file at a specific URL using `ipfs urlstore add <url>`

216
### Road to being a real feature
217 218 219 220 221
- [ ] Needs more people to use and report on how well it works.
- [ ] Need to address error states and failure conditions
- [ ] Need to write docs on usage, advantages, disadvantages
- [ ] Need to implement caching
- [ ] Need to add metrics to monitor performance
222 223 224

---

225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
## Private Networks

Allows ipfs to only connect to other peers who have a shared secret key.

### State
Experimental

### In Version
master, 0.4.7

### How to enable
Generate a pre-shared-key using [ipfs-swarm-key-gen](https://github.com/Kubuxu/go-ipfs-swarm-key-gen)):
```
go get github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen
ipfs-swarm-key-gen > ~/.ipfs/swarm.key
```

Łukasz Magiera's avatar
Łukasz Magiera committed
242 243 244
To join a given private network, get the key file from someone in the network
and save it to `~/.ipfs/swarm.key` (If you are using a custom `$IPFS_PATH`, put
it in there instead).
245

Łukasz Magiera's avatar
Łukasz Magiera committed
246
When using this feature, you will not be able to connect to the default bootstrap
Łukasz Magiera's avatar
Łukasz Magiera committed
247
nodes (Since we aren't part of your private network) so you will need to set up
Łukasz Magiera's avatar
Łukasz Magiera committed
248
your own bootstrap nodes.
249

250
First, to prevent your node from even trying to connect to the default bootstrap nodes, run:
251 252 253 254
```bash
ipfs bootstrap rm --all
```

255
Then add your own bootstrap peers with:
256 257 258 259
```bash
ipfs bootstrap add <multiaddr>
```

260
For example:
261 262 263 264 265 266 267
```
ipfs bootstrap add /ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64
```

Bootstrap nodes are no different from all other nodes in the network apart from
the function they serve.

Łukasz Magiera's avatar
Łukasz Magiera committed
268 269 270
To be extra cautious, You can also set the `LIBP2P_FORCE_PNET` environment
variable to `1` to force the usage of private networks. If no private network is
configured, the daemon will fail to start.
271 272 273 274 275 276 277 278

### Road to being a real feature
- [ ] Needs more people to use and report on how well it works
- [ ] More documentation

---

## ipfs p2p
279 280 281 282

Allows tunneling of TCP connections through Libp2p streams. If you've ever used
port forwarding with SSH (the `-L` option in openssh), this feature is quite
similar.
283 284

### State
285

286 287 288
Experimental

### In Version
289

290 291 292 293
master, 0.4.10

### How to enable

294 295 296 297 298
The `p2p` command needs to be enabled in config:

```sh
> ipfs config --json Experimental.Libp2pStreamMounting true
```
299 300 301

### How to use

Łukasz Magiera's avatar
Łukasz Magiera committed
302 303
**Netcat example:**

304 305
First, pick a protocol name for your application. Think of the protocol name as
a port number, just significantly more user-friendly. In this example, we're
306
going to use `/x/kickass/1.0`.
307

Łukasz Magiera's avatar
Łukasz Magiera committed
308
***Setup:***
309 310 311 312

1. A "server" node with peer ID `$SERVER_ID`
2. A "client" node.

Łukasz Magiera's avatar
Łukasz Magiera committed
313 314 315 316
***On the "server" node:***

First, start your application and have it listen for TCP connections on
port `$APP_PORT`.
317 318 319 320

Then, configure the p2p listener by running:

```sh
321
> ipfs p2p listen /x/kickass/1.0 /ip4/127.0.0.1/tcp/$APP_PORT
322 323
```

324
This will configure IPFS to forward all incoming `/x/kickass/1.0` streams to
325 326 327
`127.0.0.1:$APP_PORT` (opening a new connection to `127.0.0.1:$APP_PORT` per
incoming stream.

Łukasz Magiera's avatar
Łukasz Magiera committed
328
***On the "client" node:***
329

Łukasz Magiera's avatar
Łukasz Magiera committed
330 331
First, configure the client p2p dialer, so that it forwards all inbound
connections on `127.0.0.1:SOME_PORT` to the server node listening
332
on `/x/kickass/1.0`.
333 334

```sh
335
> ipfs p2p forward /x/kickass/1.0 /ip4/127.0.0.1/tcp/$SOME_PORT /ipfs/$SERVER_ID
336
```
337

338 339 340 341
Next, have your application open a connection to `127.0.0.1:$SOME_PORT`. This
connection will be forwarded to the service running on `127.0.0.1:$APP_PORT` on
the remote machine. You can test it with netcat:

Łukasz Magiera's avatar
Łukasz Magiera committed
342
***On "server" node:***
343 344 345 346
```sh
> nc -v -l -p $APP_PORT
```

Łukasz Magiera's avatar
Łukasz Magiera committed
347
***On "client" node:***
348 349 350 351 352 353 354 355 356
```sh
> nc -v 127.0.0.1 $SOME_PORT
```

You should now see that a connection has been established and be able to
exchange messages between netcat instances.

(note that depending on your netcat version you may need to drop the `-v` flag)

Łukasz Magiera's avatar
Łukasz Magiera committed
357 358 359 360 361 362 363 364 365 366 367 368 369
**SSH example**

**Setup:**

1. A "server" node with peer ID `$SERVER_ID` and running ssh server on the
   default port.
2. A "client" node.

_you can get `$SERVER_ID` by running `ipfs id -f "<id>\n"`_

***First, on the "server" node:***

```sh
370
ipfs p2p listen /x/ssh /ip4/127.0.0.1/tcp/22
Łukasz Magiera's avatar
Łukasz Magiera committed
371 372 373 374 375
```

***Then, on "client" node:***

```sh
376
ipfs p2p forward /x/ssh /ip4/127.0.0.1/tcp/2222 /ipfs/$SERVER_ID
Łukasz Magiera's avatar
Łukasz Magiera committed
377 378 379 380 381
```

You should now be able to connect to your ssh server through a libp2p connection
with `ssh [user]@127.0.0.1 -p 2222`.

382 383 384 385

### Road to being a real feature
- [ ] Needs more people to use and report on how well it works / fits use cases
- [ ] More documentation
Łukasz Magiera's avatar
Łukasz Magiera committed
386
- [ ] Support other protocols (e.g, unix domain sockets, websockets, etc.)
387 388 389

---

Dr Ian Preston's avatar
Dr Ian Preston committed
390 391 392 393 394 395 396 397 398 399
## p2p http proxy

Allows proxying of HTTP requests over p2p streams. This allows serving any standard http app over p2p streams.

### State

Experimental

### In Version

Dr Ian Preston's avatar
Dr Ian Preston committed
400
master, 0.4.19
Dr Ian Preston's avatar
Dr Ian Preston committed
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421

### How to enable

The `p2p` command needs to be enabled in config:

```sh
> ipfs config --json Experimental.Libp2pStreamMounting true
```

On the client, the p2p http proxy needs to be enabled in the config:

```sh
> ipfs config --json Experimental.P2pHttpProxy true
```

### How to use

**Netcat example:**

First, pick a protocol name for your application. Think of the protocol name as
a port number, just significantly more user-friendly. In this example, we're
Dr Ian Preston's avatar
Dr Ian Preston committed
422
going to use `/http`.
Dr Ian Preston's avatar
Dr Ian Preston committed
423 424 425 426 427 428 429 430 431 432 433 434 435 436

***Setup:***

1. A "server" node with peer ID `$SERVER_ID`
2. A "client" node.

***On the "server" node:***

First, start your application and have it listen for TCP connections on
port `$APP_PORT`.

Then, configure the p2p listener by running:

```sh
Dr Ian Preston's avatar
Dr Ian Preston committed
437
> ipfs p2p listen --allow-custom-protocol /http /ip4/127.0.0.1/tcp/$APP_PORT
Dr Ian Preston's avatar
Dr Ian Preston committed
438 439
```

Dr Ian Preston's avatar
Dr Ian Preston committed
440
This will configure IPFS to forward all incoming `/http` streams to
Dr Ian Preston's avatar
Dr Ian Preston committed
441 442 443 444
`127.0.0.1:$APP_PORT` (opening a new connection to `127.0.0.1:$APP_PORT` per incoming stream.

***On the "client" node:***

Dr Ian Preston's avatar
Dr Ian Preston committed
445
Next, have your application make a http request to `127.0.0.1:8080/p2p/$SERVER_ID/http/$FORWARDED_PATH`. This
Dr Ian Preston's avatar
Dr Ian Preston committed
446 447 448 449 450 451 452 453 454 455
connection will be forwarded to the service running on `127.0.0.1:$APP_PORT` on
the remote machine (which needs to be a http server!) with path `$FORWARDED_PATH`. You can test it with netcat:

***On "server" node:***
```sh
> echo -e "HTTP/1.1 200\nContent-length: 11\n\nIPFS rocks!" | nc -l -p $APP_PORT
```

***On "client" node:***
```sh
Dr Ian Preston's avatar
Dr Ian Preston committed
456
> curl http://localhost:8080/p2p/$SERVER_ID/http/
Dr Ian Preston's avatar
Dr Ian Preston committed
457 458 459 460
```

You should now see the resulting http response: IPFS rocks!

Dr Ian Preston's avatar
Dr Ian Preston committed
461 462
### Custom protocol names
We also support use of protocol names of the form /x/$NAME/http where $NAME doesn't contain any "/"'s
Dr Ian Preston's avatar
Dr Ian Preston committed
463 464 465 466 467 468 469 470

### Road to being a real feature
- [ ] Needs p2p streams to graduate from experiments
- [ ] Needs more people to use and report on how well it works / fits use cases
- [ ] More documentation

---

471 472 473 474 475 476 477 478 479
## Circuit Relay

Allows peers to connect through an intermediate relay node when there
is no direct connectivity.

### State
Experimental

### In Version
480
master, 0.4.11
481 482 483

### How to enable

Łukasz Magiera's avatar
Łukasz Magiera committed
484 485 486
The relay transport is enabled by default, which allows peers to dial through
relay and listens for incoming relay connections. The transport can be disabled
by setting `Swarm.DisableRelay = true` in the configuration.
487

Łukasz Magiera's avatar
Łukasz Magiera committed
488 489 490 491
By default, peers don't act as intermediate nodes (relays). This can be enabled
by setting `Swarm.EnableRelayHop = true` in the configuration. Note that the
option needs to be set before online services are started to have an effect; an
already online node would have to be restarted.
492 493 494 495 496 497 498 499

### Basic Usage:

In order to connect peers QmA and QmB through a relay node QmRelay:

- Both peers should connect to the relay:
`ipfs swarm connect /transport/address/ipfs/QmRelay`
- Peer QmA can then connect to peer QmB using the relay:
Łukasz Magiera's avatar
Łukasz Magiera committed
500
`ipfs swarm connect /ipfs/QmRelay/p2p-circuit/ipfs/QmB`
501 502 503 504 505 506 507 508 509 510 511

Peers can also connect with an unspecific relay address, which will
try to dial through known relays:
`ipfs swarm connect /p2p-circuit/ipfs/QmB`

Peers can see their (unspecific) relay address in the output of
`ipfs swarm addrs listen`

### Road to being a real feature

- [ ] Needs more people to use it and report on how well it works.
Łukasz Magiera's avatar
Łukasz Magiera committed
512 513 514 515 516 517 518
- [ ] Advertise relay addresses to the DHT for NATed or otherwise unreachable
      peers.
- [ ] Active relay discovery for specific relay address advertisement. We would
      like advertised relay addresses to designate specific relays for efficient
      dialing.
- [ ] Dialing priorities for relay addresses; arguably, relay addresses should
      have lower priority than direct dials.
519 520 521

## Plugins

Jeromy Johnson's avatar
Jeromy Johnson committed
522 523 524
### In Version
0.4.11

525 526 527
### State
Experimental

528 529 530 531 532 533 534 535 536 537
Plugins allow to add functionality without the need to recompile the daemon.

### Basic Usage:

See [Plugin docs](./plugins.md)

### Road to being a real feature

- [ ] Better support for platforms other than Linux
- [ ] More plugins and plugin types
Jeromy Johnson's avatar
Jeromy Johnson committed
538
- [ ] Feedback on stability
539 540 541 542 543 544 545 546 547 548 549 550 551 552

 ## Badger datastore

 ### In Version
 0.4.11

 Badger-ds is new datastore implementation based on
 https://github.com/dgraph-io/badger

 ### Basic Usage

 ```
 $ ipfs init --profile=badgerds
 ```
553
 or install https://github.com/ipfs/ipfs-ds-convert/ and
554 555 556 557 558 559 560 561 562 563 564 565
 ```
 [BACKUP ~/.ipfs]
 $ ipfs config profile apply badgerds
 $ ipfs-ds-convert convert
 ```

###

### Road to being a real feature

- [ ] Needs more testing
- [ ] Make sure there are no unknown major problems
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587

## Directory Sharding / HAMT

### In Version
0.4.8

### State
Experimental

Allows to create directories with unlimited number of entries - currently
size of unixfs directories is limited by the maximum block size

### Basic Usage:

```
ipfs config --json Experimental.ShardingEnabled true
```

### Road to being a real feature

- [ ] Make sure that objects that don't have to be sharded aren't
- [ ] Generalize sharding and define a new layer between IPLD and IPFS
588 589 590 591 592 593 594

---

## IPNS pubsub

### In Version

595
0.4.14
596 597 598 599 600 601 602

### State

Experimental, default-disabled.

Utilizes pubsub for publishing ipns records in real time.

603 604 605
When it is enabled:
- IPNS publishers push records to a name-specific pubsub topic,
  in addition to publishing to the DHT.
vyzo's avatar
vyzo committed
606
- IPNS resolvers subscribe to the name-specific topic on first
vyzo's avatar
vyzo committed
607
  resolution and receive subsequently published records through pubsub
vyzo's avatar
vyzo committed
608 609 610 611
  in real time. This makes subsequent resolutions instant, as they
  are resolved through the local cache. Note that the initial
  resolution still goes through the DHT, as there is no message
  history in pubsub.
612 613 614

Both the publisher and the resolver nodes need to have the feature enabled for it
to work effectively.
615

616 617 618 619 620 621 622 623
### How to enable

run your daemon with the `--enable-namesys-pubsub` flag; enables pubsub.

### Road to being a real feature

- [ ] Needs more people to use and report on how well it works
- [ ] Add a mechanism for last record distribution on subscription,
Marten Seemann's avatar
Marten Seemann committed
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
  so that we don't have to hit the DHT for the initial resolution.
  Alternatively, we could republish the last record periodically.



## QUIC

### In Version

0.4.18

### State

Experiment, disabled by default

### How to enable

Modify your ipfs config:

```
ipfs config --json Experimental.QUIC true
```

For listening on a QUIC address, add it the swarm addresses, e.g. `/ip4/0.0.0.0/udp/4001/quic`.


### Road to being a real feature

- [ ] The IETF QUIC specification needs to be finalised.
- [ ] Make sure QUIC connections work reliably
- [ ] Make sure QUIC connection offer equal or better performance than TCP connections on real world networks
- [ ] Finalize libp2p-TLS handshake spec.
vyzo's avatar
vyzo committed
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685


## AutoRelay

### In Version

0.4.19-dev

### State

Experimental, disabled by default.

Automatically discovers relays and advertises relay addresses when the node is behind an impenetrable NAT.

### How to enable

Modify your ipfs config:

```
ipfs config --json Swarm.EnableAutoRelay true
```

Bootstrappers (and other public nodes) need to also enable the AutoNATService:
```
ipfs config --json Swarm.EnableAutoNATService true
```

### Road to being a real feature

- [ ] needs testing
686 687 688 689 690 691


## TLS 1.3 as default handshake protocol

### State

Steven Allen's avatar
Steven Allen committed
692 693 694
Every go-ipfs node (>=0.4.21) accepts secio and TLS 1.3 connections but prefers
secio over TLS when dialing. To prefer TLS when dialing, you'll have to enable
this feature.
695 696 697 698 699 700 701 702 703 704 705 706

### How to enable

Modify your ipfs config:

```
ipfs config --json Experimental.PreferTLS true
```

### Road to being a real feature

- [ ] needs testing
Steven Allen's avatar
Steven Allen committed
707
- [ ] needs adoption