Skip to content

Commit 671d123

Browse files
enoldevwalkerlj0
andauthored
libp2p tutorials: Create simple node (#252)
Co-authored-by: Lindsay Walker <[email protected]>
1 parent a9d0a26 commit 671d123

File tree

6 files changed

+256
-6
lines changed

6 files changed

+256
-6
lines changed
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
title: "Create A libp2p Node (Tutorial)"
3+
description: "Use libp2p-go to create to a libp2p node"
4+
draft: false
5+
menu:
6+
curriculum:
7+
parent: "curriculum-libp2p"
8+
weight: 312
9+
category: tutorial
10+
level:
11+
- deep
12+
---
13+
## Background
14+
In this tutorial, you will use a boilerplate Go project to set up two libp2p nodes and connect them, so you can begin to explore the capabilities of libp2p, such as data transmission, peer identification, routing, messaging, content discovery, and more.
15+
16+
By the end of the exercise, you should be able to:
17+
18+
* Create a new libp2p node
19+
* Print the node's ID and multiaddresses
20+
* Configure the node at a basic level
21+
* Connect to another node
22+
23+
![Application diagram](diagram.png)
24+
25+
## Prerequisites
26+
27+
* You must have [Go installed](https://go.dev/doc/install). In this exercise, version 1.18 is used.
28+
* You can also install [multiple versions of Go](https://go.dev/doc/manage-install#installing-multiple).
29+
* Clone or fork the `https://github.com/protocol/launchpad-tutorials` [Git repository](https://github.com/protocol/launchpad-tutorials), which contains all the sample applications used in the Launchpad program.
30+
31+
## Instructions
32+
33+
* Open the `/libp2p-go-simple-code` folder of the `launchpad-tutorials` repository in an IDE of your preference. The `app` subfolder contains the template that you will complete.
34+
35+
### Video
36+
This video will demonstrate how you can create simple libp2p node in a Go application.
37+
38+
{{< youtube Qa-eAvXp6LY >}}
39+
40+
### Review the "main" Function
41+
42+
In the `main.go` file, review the code, at about line 40.
43+
There are several functions that are called which you will implement in this tutorial.
44+
The `main()` function manages the flow of the program by calling different helper functions.
45+
46+
### Create the Source Node
47+
48+
* In the `createSourceNode` function, create a libp2p node by using the `libp2p.New()` function.
49+
This method returns a [host.Host](https://github.com/libp2p/go-libp2p/blob/master/core/host/host.go#L25) interface, which you can use to manage the node.
50+
51+
```go
52+
func createSourceNode() host.Host {
53+
node, err := libp2p.New()
54+
if err != nil {
55+
panic(err)
56+
}
57+
58+
return node
59+
}
60+
```
61+
62+
By default, the node gets an ID and listens at a random TCP port.
63+
64+
### Create the Target Node
65+
66+
* Now, in the `createTargetNode` function, create a new node that listens at the `8007` TCP port. You can configure a node by passing several [Option](https://github.com/libp2p/go-libp2p/blob/master/libp2p.go#L13) structs to the `New(...)` method.
67+
68+
```go
69+
func createTargetNode() host.Host {
70+
node, err := libp2p.New(
71+
libp2p.ListenAddrStrings(
72+
"/ip4/0.0.0.0/tcp/8007",
73+
),
74+
)
75+
if err != nil {
76+
panic(err)
77+
}
78+
79+
return node
80+
}
81+
```
82+
83+
### Connect the Nodes
84+
85+
* So far, you have created two nodes; now, let's connect `sourceNode` to `targetNode`.
86+
The `host.Host` interface contains a `Connect` method that you can use.
87+
The `Connect` method expects a `peer.AddrInfo` struct, which is an abstraction that represents the _location_ of a peer.
88+
To create a `peer.AddrInfo` struct with the data of the node, you can use the [host.InfoFromHost](https://github.com/libp2p/go-libp2p/blob/master/core/host/helpers.go#L6) function.
89+
90+
```go
91+
func connectToTargetNode(sourceNode host.Host, targetNode host.Host) {
92+
targetNodeAddressInfo := host.InfoFromHost(targetNode)
93+
94+
err := sourceNode.Connect(context.Background(), *targetNodeAddressInfo)
95+
if err != nil {
96+
panic(err)
97+
}
98+
}
99+
```
100+
101+
### Count the Number of Peers of the Source Node
102+
103+
* To verify that the connection works, you can list the peers connected to the node. In this example, you will simply count the number of peers and return that number to verify that your libp2p node is connected to peers.
104+
105+
```go
106+
func countSourceNodePeers(sourceNode host.Host) int {
107+
return len(sourceNode.Network().Peers())
108+
}
109+
```
110+
111+
### Run the Program
112+
113+
* Now, test that the two nodes are connected by running the application. In your terminal, `cd` to the `/libp2p-go-simple-node/app` directory and run `go run .`
114+
115+
You should see the following output, with the number of source node peers:
116+
117+
```bash
118+
> go run .
119+
-- SOURCE NODE INFORMATION --
120+
ID: 12D3KooWCGcgrrrfDwzLmNeZ25543kYcewKxXzgDkGJGNXw1ZUf3
121+
Multiaddresses: /ip4/192.168.0.10/tcp/63678, /ip4/127.0.0.1/tcp/63678, /ip6/::1/tcp/63681
122+
-- TARGET NODE INFORMATION --
123+
ID: 12D3KooWLkzhtJxcSnasfzkXGQzgKGqxGtUDpACZSXt3HM4Rn3op
124+
Multiaddresses: /ip4/192.168.0.10/tcp/8007, /ip4/127.0.0.1/tcp/8007
125+
Source node peers: 1
126+
```
127+
128+
You can see an example of the [completed code here](https://github.com/protocol/launchpad-tutorials/blob/main/libp2p-go-simple-node/solution/main.go)
129+
130+
Now that you have two nodes connected and communicating, you can start to implement the many [features available with libp2p](https://libp2p.io/). In a later tutorial, you will learn how to start a libp2p stream.

content/en/curriculum/libp2p/dht/index.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ draft: false
55
menu:
66
curriculum:
77
parent: "curriculum-libp2p"
8-
weight: 312
8+
weight: 315
99
category: lecture
1010
level:
1111
- deep
@@ -32,7 +32,7 @@ The mathematical explanation about the distance function is not trivial, and it
3232
## The Routing Table
3333

3434
The distance metrics can be calculated not only between keys and peer IDs, but also between peer IDs themselves. In order to facilitate the discovery of peers in the network (i.e. be able to answer `FIND_NODES` operation), a peer keeps a list of peers divided into buckets depending on the distance to them. Buckets for close distances are bigger.
35-
Thus, a node may not be storing certain key, but it is usually able to provide a list of known nodes that are closer to the key than itself, thus helping in the lookup for the closest nodes.
35+
Thus, a node may not be storing certain key, but it is usually able to provide a list of known nodes that are closer to the key than itself, thus helping in the lookup for the closest nodes.
3636

3737
The internals of the routing table are beyond the outcomes of this lecture, but you can read more on the topic [here](https://en.wikipedia.org/wiki/Kademlia#Fixed-size_routing_tables). You can also take a look at the [Go implementation](https://github.com/libp2p/go-libp2p-kbucket/blob/f0be035294ac4f5e939af13ddc1dd24273b7d881/table.go#L25) of the routing table.
3838

@@ -101,7 +101,7 @@ The nodes with the lowest distance to the key are selected: `Peer 6` and `Peer 7
101101

102102
Note that the previous example is just a very **high-level** explanation of the algorithm. For a deeper look, refer to the [specification](https://github.com/libp2p/specs/tree/master/kad-dht#value-retrieval). For example, a validation strategy is needed because several peers might return different values for the same key.
103103

104-
In storage systems (e.g., IPFS), a DHT key might represent a specific file's CID. Therefore, searching for a particular key means finding what peers hold a specific file.
104+
In storage systems (e.g., IPFS), a DHT key might represent a specific file's CID. Therefore, searching for a particular key means finding what peers hold a specific file.
105105

106106
### Advertising Content
107107

@@ -120,4 +120,4 @@ The DHT is a complex topic that involves understanding several concepts. The fol
120120
If you want to get more information, refer to the following links:
121121

122122
- libp2p DHT Go Implementation ([GitHub](https://github.com/libp2p/go-libp2p-kad-dht/blob/4371650e37662cdfd9f5777240c67b861af26092/dht.go#L78))
123-
- libp2p DHT Specification ([GitHub](https://github.com/libp2p/specs/blob/master/kad-dht/README.md))
123+
- libp2p DHT Specification ([GitHub](https://github.com/libp2p/specs/blob/master/kad-dht/README.md))
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{{ if .Site.Params.options.collapsibleSidebar -}}
2+
<ul class="list-unstyled collapsible-sidebar">
3+
{{ $currentPage := . -}}
4+
{{ range $index, $element := .Site.Menus.curriculum -}}
5+
{{- $active := or ($currentPage.IsMenuCurrent "curriculum" .) ($currentPage.HasMenuCurrent "curriculum" .) -}}
6+
{{- $active = or $active (eq $currentPage.Section .Identifier) -}}
7+
<li class="mb-1">
8+
<button class="btn btn-toggle align-items-center rounded collapsed" data-bs-toggle="collapse" data-bs-target="#section-{{ .Identifier }}" aria-expanded="{{ if $active }}true{{ else }}false{{ end }}">
9+
{{ .Name }}
10+
</button>
11+
{{ if .HasChildren -}}
12+
<div class="collapse{{ if $active }} show{{ end }}" id="section-{{ .Identifier }}" id="section-{{ .Identifier }}">
13+
<ul class="btn-toggle-nav list-unstyled fw-normal pb-1 small">
14+
{{ range .Children -}}
15+
{{- $active := or ($currentPage.IsMenuCurrent "curriculum" .) ($currentPage.HasMenuCurrent "curriculum" .) -}}
16+
{{- $active = or $active (eq $currentPage.Section .Identifier) -}}
17+
<li style="display: flex; align-items: center;" data-content-level="{{ .Page.Params.level }}">
18+
{{ if eq .Page.Params.category "lecture" }}
19+
<img src="/icons/lecture.png" width="20" height="20" />
20+
{{ else }}
21+
<img src="/icons/tutorial.png" width="20" height="20" />
22+
{{ end }}
23+
<a class="docs-link rounded{{ if $active }} active{{ end }}" href="{{ .URL | relURL }}" style="margin-left: 0.4rem">{{ .Name }}</a>
24+
</li>
25+
{{ end -}}
26+
</ul>
27+
</div>
28+
{{ end -}}
29+
</li>
30+
{{ end -}}
31+
</ul>
32+
{{ else -}}
33+
{{ $currentPage := . -}}
34+
{{ range .Site.Menus.curriculum -}}
35+
<h3 class="h6 text-uppercase">{{ .Name }}</h3>
36+
{{ if .HasChildren -}}
37+
<ul class="list-unstyled">
38+
{{ range .Children -}}
39+
{{- $active := or ($currentPage.IsMenuCurrent "curriculum" .) ($currentPage.HasMenuCurrent "curriculum" .) -}}
40+
{{- $active = or $active (eq $currentPage.Section .Identifier) -}}
41+
<li><a class="docs-link{{ if $active }} active{{ end }}" href="{{ .URL | relURL }}">{{ .Name }}</a></li>
42+
{{ end -}}
43+
</ul>
44+
{{ end -}}
45+
{{ end -}}
46+
{{ end -}}

theme.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ tags = ["landing page", "documentation", "blog", "minimal", "modern", "customiza
1010
features = ["security aware", "fast by default", "seo-ready", "development tools", "bootstrap framework", "netlify-ready", "full text search", "page layouts", "dark mode"]
1111

1212
[author]
13-
name = "Henk Verlinde"
14-
homepage = "https://henkverlinde.com"
13+
name = "Protocol Labs Launchpad Team"
14+
homepage = "https://github.com/protocol"

tutorial-temp.md

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
title: "Title (Tutorial)"
3+
description: "Deep/Shallow Dive Tutorial – Subtitle"
4+
draft: false
5+
menu:
6+
curriculum:
7+
parent: ""
8+
weight: 0
9+
category: tutorial
10+
level:
11+
- shallow
12+
- deep
13+
---
14+
15+
## Background
16+
short ~1-2 paragraphs with context
17+
18+
## Prerequisites
19+
Write about _all_ software and dependencies you will need to have installed, with relevant links to resources for where you can download/ read instruction on how to install
20+
* NodeJS vx.xx.xx
21+
* Go Version x.xx ^
22+
* Even things like Homebrew
23+
24+
25+
## Instructions
26+
Sentence?
27+
28+
### Video
29+
30+
{{< youtube i100RhwZUnQ >}}
31+
<!-- The URL to this video was: https://www.youtube.com/watch?v=i100RhwZUnQ -->
32+
33+
34+
### Title 1 that describes what you will do
35+
Information & context
36+
* Specific to-do `command`
37+
* Specific to-do
38+
```
39+
some code
40+
41+
```
42+
### Title 2 that describes what you will do
43+
Information & context
44+
* Specific to-do `command`
45+
* Specific to-do
46+
```
47+
some code
48+
49+
```
50+
### Title 3 that describes what you will do
51+
Information & context
52+
* Specific to-do `command`
53+
* Specific to-do
54+
```
55+
some code
56+
57+
```
58+
59+
### Title n that describes what you will do
60+
Information & context
61+
* Specific to-do `command`
62+
* Specific to-do
63+
```
64+
some code
65+
66+
```
67+
68+
<!-- Summary -->
69+
Now you can ----- . Next you will/can learn to ... See an example of the completed code **<Link to branch & file with completed code>**
70+
71+
#### Resources
72+
* [Video Script]()
73+
* [Docs]()
74+
* Other Thing

0 commit comments

Comments
 (0)