Skip to content

Instantly share code, notes, and snippets.

@adlrocha
Last active June 9, 2021 06:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adlrocha/bac46a74d47aa3ea41a579f45511ec8f to your computer and use it in GitHub Desktop.
Save adlrocha/bac46a74d47aa3ea41a579f45511ec8f to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"context"
"fmt"
"time"
"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/peer"
xr "github.com/libp2p/go-routing-language/syntax"
"github.com/libp2p/go-smart-record/protocol"
)
func main() {
ctx := context.Background()
fmt.Println("[*] Starting hosts")
// ------------------------------
// Initializing three hosts
// ------------------------------
h1, err := libp2p.New(ctx)
if err != nil {
panic(err)
}
h2, err := libp2p.New(ctx)
if err != nil {
panic(err)
}
h3, err := libp2p.New(ctx)
if err != nil {
panic(err)
}
defer h1.Close()
defer h2.Close()
// Wait until hosts are ready
time.Sleep(1 * time.Second)
// ------------------------------
// Connecting them
// ------------------------------
fmt.Println("[*] Connecting peers")
err = DialOtherPeer(ctx, h1, *host.InfoFromHost(h2))
if err != nil {
panic(err)
}
// -----------------------------------
// h1 is the server and h2 the client
// -----------------------------------
fmt.Println("[*] h1 is the SR server and h2 the client")
_, _ = protocol.NewSmartRecordServer(ctx, h1)
smClient, _ := protocol.NewSmartRecordClient(ctx, h2)
// Making h3 reachable
reachable := fmt.Sprintf("%s/p2p/%s", h3.Addrs()[0].String(), h3.ID().Pretty())
unreachableAddr := "/ip4/127.0.0.1/tcp/44783/p2p/12D3KooWKRyzVWW6ChFjQjK4miCty85Niy48tpPV95XdKu1BcvMA"
// -----------------------------------
// Creating the records
// -----------------------------------
fmt.Println("[*] Creating new records with `connectivity` and `dialable` tags")
in1 := xr.Dict{
Pairs: xr.Pairs{
xr.Pair{Key: xr.Predicate{
Tag: "link",
Positional: xr.Nodes{xr.String{"Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu"}},
},
Value: xr.Dict{xr.Pairs{
xr.Pair{
Key: xr.String{"/ipfs/Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu"},
Value: xr.Predicate{Tag: "peer", Positional: xr.Nodes{xr.String{h3.ID().String()}}},
},
xr.Pair{
Key: xr.String{"sectorID1"},
Value: xr.Predicate{Tag: "sealed", Positional: xr.Nodes{xr.String{"t0112"}}},
},
}},
},
xr.Pair{Key: xr.String{"Providers"},
Value: xr.Dict{xr.Pairs{
xr.Pair{Key: xr.String{Value: h3.ID().String()}, Value: xr.Predicate{
Tag: "connectivity",
Named: xr.Pairs{xr.Pair{Key: xr.String{"address"}, Value: xr.Predicate{
Tag: "multiaddr",
Positional: xr.Nodes{xr.String{reachable}},
},
},
}}},
xr.Pair{Key: xr.String{Value: "QmUnreach"}, Value: xr.Predicate{
Tag: "dialable",
Named: xr.Pairs{xr.Pair{Key: xr.String{"address"}, Value: xr.Predicate{
Tag: "multiaddr",
Positional: xr.Nodes{xr.String{unreachableAddr}},
},
},
}}},
xr.Pair{Key: xr.String{Value: "QmXFor"}, Value: xr.Predicate{
Tag: "multiaddr",
Positional: xr.Nodes{xr.String{"/ip4/multiaddr3"}},
}},
}}},
},
}
in2 := xr.Dict{
Pairs: xr.Pairs{
xr.Pair{Key: xr.Predicate{
Tag: "link",
Positional: xr.Nodes{xr.String{"Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu"}},
},
Value: xr.Dict{xr.Pairs{
xr.Pair{
Key: xr.String{"/ipfs/Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu"},
Value: xr.Predicate{Tag: "peer", Positional: xr.Nodes{xr.String{h3.ID().String()}}},
},
xr.Pair{
Key: xr.String{"sectorID2"},
Value: xr.Predicate{Tag: "unsealed", Positional: xr.Nodes{xr.String{"t0113"}}},
},
}},
},
xr.Pair{Key: xr.String{"Providers"},
Value: xr.Dict{xr.Pairs{xr.Pair{
Key: xr.String{h3.ID().String()}, Value: xr.Predicate{
Tag: "dialable",
Named: xr.Pairs{xr.Pair{Key: xr.String{"address"}, Value: xr.Predicate{
Tag: "multiaddr",
Positional: xr.Nodes{xr.String{reachable}},
},
},
}}}}}},
},
}
k := "234"
// -----------------------------------
// Sending updates to server
// -----------------------------------
// Update record with 60 seconds of TTL
fmt.Println("[*] Updating k=234 with in1 and TTL=60")
err = smClient.Update(ctx, k, h1.ID(), in1, 60*time.Second)
if err != nil {
panic(err)
}
var w bytes.Buffer
in1.WritePretty(&w)
fmt.Println(w.String())
w.Reset()
fmt.Println("[*] Update 1 successful")
// Update record with 60 seconds of TTL
fmt.Println("[*] Updating k=234 with in2 and TTL=60")
err = smClient.Update(ctx, k, h1.ID(), in2, 60*time.Second)
if err != nil {
panic(err)
}
in2.WritePretty(&w)
fmt.Println(w.String())
w.Reset()
fmt.Println("[*] Update 2 successful")
// -----------------------------------
// Fetching record
// -----------------------------------
// Get Record stored
fmt.Println("[*] Getting updated record from peer")
out, err := smClient.Get(ctx, k, h1.ID())
if err != nil {
panic(err)
}
fmt.Println("[*] Record Key", k)
for k, v := range *out {
fmt.Println("Peer:", k)
var w bytes.Buffer
v.WritePretty(&w)
fmt.Println(w.String())
}
}
// DialOtherPeers connects to a set of peers in the experiment.
func DialOtherPeer(ctx context.Context, self host.Host, ai peer.AddrInfo) error {
if err := self.Connect(ctx, ai); err != nil {
return fmt.Errorf("Error while dialing peer %v: %w", ai.Addrs, err)
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment