Skip to content

Commit

Permalink
feat: remote backend
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Apr 18, 2024
1 parent ba66742 commit 3c42cb5
Show file tree
Hide file tree
Showing 4 changed files with 317 additions and 121 deletions.
7 changes: 6 additions & 1 deletion gc.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ import (
)

// GC is a really stupid simple algorithm where we just delete things until
// weve deleted enough things
// we've deleted enough things. It is no-op if the current setup does not have
// a blockstore.
func (nd *Node) GC(ctx context.Context, todelete int64) error {
if nd.blockstore == nil {
return nil

Check warning on line 15 in gc.go

View check run for this annotation

Codecov / codecov/patch

gc.go#L15

Added line #L15 was not covered by tests
}

keys, err := nd.blockstore.AllKeysChan(ctx)
if err != nil {
return err
Expand Down
23 changes: 19 additions & 4 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,27 @@ func withRequestLogger(next http.Handler) http.Handler {
}

func setupGatewayHandler(cfg Config, nd *Node) (http.Handler, error) {
backend, err := gateway.NewBlocksBackend(
nd.bsrv,
var (
backend gateway.IPFSBackend
err error
)

options := []gateway.BackendOption{
gateway.WithValueStore(nd.vs),
gateway.WithNameSystem(nd.ns),
gateway.WithResolver(nd.resolver),
)
gateway.WithResolver(nd.resolver), // May be nil, but that is fine.
}

if len(cfg.RemoteBackends) > 0 && cfg.RemoteBackendMode == RemoteBackendCAR {
var fetcher gateway.CarFetcher
fetcher, err = gateway.NewRemoteCarFetcher(cfg.RemoteBackends, nil)
if err != nil {
return nil, err

Check warning on line 103 in handlers.go

View check run for this annotation

Codecov / codecov/patch

handlers.go#L100-L103

Added lines #L100 - L103 were not covered by tests
}
backend, err = gateway.NewCarBackend(fetcher, options...)

Check warning on line 105 in handlers.go

View check run for this annotation

Codecov / codecov/patch

handlers.go#L105

Added line #L105 was not covered by tests
} else {
backend, err = gateway.NewBlocksBackend(nd.bsrv, options...)
}
if err != nil {
return nil, err
}
Expand Down
134 changes: 90 additions & 44 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,32 @@ Generate an identity seed and launch a gateway:
EnvVars: []string{"RAINBOW_IPNS_MAX_CACHE_TTL"},
Usage: "Optional cap on caching duration for IPNS/DNSLink lookups. Set to 0 to respect original TTLs",
},
&cli.BoolFlag{
Name: "no-bitswap",
Value: false,
EnvVars: []string{"RAINBOW_NO_BITSWAP"},
Usage: "Disable Bitswap. Incompatible with --peering-shared-cache",
},
&cli.StringSliceFlag{
Name: "remote-backends",
Value: cli.NewStringSlice(),
EnvVars: []string{"RAINBOW_REMOTE_BACKENDS"},
Usage: "Trustless remote gateways to use as backend(comma-separated). You must set --no-bitswap to use this option",
},
&cli.StringFlag{
Name: "remote-backends-mode",
Value: "block",
EnvVars: []string{"RAINBOW_REMOTE_BACKENDS_MODE"},
Usage: "Whether to fetch raw blocks or CARs from the remote backends. Options are 'block' or 'car'",
Action: func(ctx *cli.Context, s string) error {
switch RemoteBackendMode(s) {
case RemoteBackendBlock, RemoteBackendCAR:
return nil
default:
return errors.New("invalid value for --remote-backend-mode: use 'block' or 'car'")

Check warning on line 273 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L268-L273

Added lines #L268 - L273 were not covered by tests
}
},
},
}

app.Commands = []*cli.Command{
Expand Down Expand Up @@ -287,55 +313,64 @@ share the same seed as long as the indexes are different.

var seed string
var priv crypto.PrivKey
var peeringAddrs []peer.AddrInfo
var index int

Check warning on line 317 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L316-L317

Added lines #L316 - L317 were not covered by tests
var err error

credDir := os.Getenv("CREDENTIALS_DIRECTORY")
secretsDir := ddir
noBitswap := cctx.Bool("no-bitswap")
dhtRouting := DHTRouting(cctx.String("dht-routing"))
seedPeering := cctx.Bool("seed-peering")
noLibp2p := noBitswap && dhtRouting == DHTOff && !seedPeering

Check warning on line 323 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L320-L323

Added lines #L320 - L323 were not covered by tests

if len(credDir) > 0 {
secretsDir = credDir
}
// Only load secrets if we need Libp2p.
if !noLibp2p {
credDir := os.Getenv("CREDENTIALS_DIRECTORY")
secretsDir := ddir

Check warning on line 328 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L326-L328

Added lines #L326 - L328 were not covered by tests

// attempt to read seed from disk
seedBytes, err := os.ReadFile(filepath.Join(secretsDir, "seed"))
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
// set seed from command line or env-var
seed = cctx.String("seed")
} else {
return fmt.Errorf("error reading seed credentials: %w", err)
if len(credDir) > 0 {
secretsDir = credDir

Check warning on line 331 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L330-L331

Added lines #L330 - L331 were not covered by tests
}
} else {
seed = strings.TrimSpace(string(seedBytes))
}

index := cctx.Int("seed-index")
if len(seed) > 0 && index >= 0 {
fmt.Println("Deriving identity from seed")
priv, err = deriveKey(seed, deriveKeyInfo(index))
} else {
fmt.Println("Setting identity from libp2p.key")
keyFile := filepath.Join(secretsDir, "libp2p.key")
priv, err = loadOrInitPeerKey(keyFile)
}
if err != nil {
return err
}

var peeringAddrs []peer.AddrInfo
for _, maStr := range cctx.StringSlice("peering") {
if len(seed) > 0 && index >= 0 {
maStr, err = replaceRainbowSeedWithPeer(maStr, seed)
if err != nil {
return err
// attempt to read seed from disk
seedBytes, err := os.ReadFile(filepath.Join(secretsDir, "seed"))
if err != nil {
if errors.Is(err, fs.ErrNotExist) {

Check warning on line 337 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L335-L337

Added lines #L335 - L337 were not covered by tests
// set seed from command line or env-var
seed = cctx.String("seed")
} else {
return fmt.Errorf("error reading seed credentials: %w", err)

Check warning on line 341 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L339-L341

Added lines #L339 - L341 were not covered by tests
}
} else {
seed = strings.TrimSpace(string(seedBytes))

Check warning on line 344 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L343-L344

Added lines #L343 - L344 were not covered by tests
}

ai, err := peer.AddrInfoFromString(maStr)
index = cctx.Int("seed-index")
if len(seed) > 0 && index >= 0 {
fmt.Println("Deriving identity from seed")
priv, err = deriveKey(seed, deriveKeyInfo(index))
} else {
fmt.Println("Setting identity from libp2p.key")
keyFile := filepath.Join(secretsDir, "libp2p.key")
priv, err = loadOrInitPeerKey(keyFile)

Check warning on line 354 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L347-L354

Added lines #L347 - L354 were not covered by tests
}
if err != nil {
return err
}
peeringAddrs = append(peeringAddrs, *ai)

for _, maStr := range cctx.StringSlice("peering") {
if len(seed) > 0 && index >= 0 {
maStr, err = replaceRainbowSeedWithPeer(maStr, seed)
if err != nil {
return err

Check warning on line 364 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L360-L364

Added lines #L360 - L364 were not covered by tests
}
}

ai, err := peer.AddrInfoFromString(maStr)
if err != nil {
return err

Check warning on line 370 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L368-L370

Added lines #L368 - L370 were not covered by tests
}
peeringAddrs = append(peeringAddrs, *ai)

Check warning on line 372 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L372

Added line #L372 was not covered by tests
}
}

cfg := Config{
Expand All @@ -351,23 +386,32 @@ share the same seed as long as the indexes are different.
MaxFD: cctx.Int("max-fd"),
InMemBlockCache: cctx.Int64("inmem-block-cache"),
RoutingV1Endpoints: cctx.StringSlice("http-routers"),
DHTRouting: DHTRouting(cctx.String("dht-routing")),
DHTRouting: dhtRouting,

Check warning on line 389 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L389

Added line #L389 was not covered by tests
DHTSharedHost: cctx.Bool("dht-shared-host"),
NoBitswap: noBitswap,

Check warning on line 391 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L391

Added line #L391 was not covered by tests
IpnsMaxCacheTTL: cctx.Duration("ipns-max-cache-ttl"),
DenylistSubs: cctx.StringSlice("denylists"),
Peering: peeringAddrs,
PeeringCache: cctx.Bool("peering-shared-cache"),
Seed: seed,
SeedIndex: index,
SeedPeering: cctx.Bool("seed-peering"),
SeedPeering: seedPeering,
SeedPeeringMaxIndex: cctx.Int("seed-peering-max-index"),
RemoteBackends: cctx.StringSlice("remote-backends"),
RemoteBackendMode: RemoteBackendMode(cctx.String("remote-backends-mode")),

Check warning on line 401 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L395-L401

Added lines #L395 - L401 were not covered by tests
GCInterval: cctx.Duration("gc-interval"),
GCThreshold: cctx.Float64("gc-threshold"),
}

var gnd *Node

Check warning on line 406 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L406

Added line #L406 was not covered by tests

goLog.Debugf("Rainbow config: %+v", cfg)

gnd, err := Setup(cctx.Context, cfg, priv, cdns)
if noLibp2p {
gnd, err = SetupNoLibp2p(cctx.Context, cfg, cdns)
} else {
gnd, err = Setup(cctx.Context, cfg, priv, cdns)

Check warning on line 413 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L410-L413

Added lines #L410 - L413 were not covered by tests
}
if err != nil {
return err
}
Expand All @@ -386,11 +430,13 @@ share the same seed as long as the indexes are different.
}

fmt.Printf("Starting %s %s\n", name, version)
pid, err := peer.IDFromPublicKey(priv.GetPublic())
if err != nil {
return err
if priv != nil {
pid, err := peer.IDFromPublicKey(priv.GetPublic())
if err != nil {
return err

Check warning on line 436 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L433-L436

Added lines #L433 - L436 were not covered by tests
}
fmt.Printf("PeerID: %s\n\n", pid)

Check warning on line 438 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L438

Added line #L438 was not covered by tests
}
fmt.Printf("PeerID: %s\n\n", pid)
registerVersionMetric(version)
registerIpfsNodeCollector(gnd)

Expand Down
Loading

0 comments on commit 3c42cb5

Please sign in to comment.