mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-22 10:57:42 +08:00
* Delegated Routing. Implementation of Reframe specs (https://github.com/ipfs/specs/blob/master/REFRAME.md) using go-delegated-routing library. * Requested changes. * Init using op string * Separate possible ContentRouters for TopicDiscovery. If we don't do this, we have a ciclic dependency creating TieredRouter. Now we can create first all possible content routers, and after that, create Routers. * Set dht default routing type * Add tests and remove uneeded code * Add documentation. * docs: Routing.Routers * Requested changes. Signed-off-by: Antonio Navarro Perez <antnavper@gmail.com> * Add some documentation on new fx functions. * Add changelog entry and integration tests * test: sharness for 'dht' in 'routing' commands Since 'routing' is currently the same as 'dht' (minus query command) we need to test both, that way we won't have unnoticed divergence in the default behavior. * test(sharness): delegated routing via reframe URL * Add more tests for delegated routing. * If any put operation fails, the tiered router will fail. * refactor: Routing.Routers: Parameters.Endpoint As agreed in https://github.com/ipfs/kubo/pull/8997#issuecomment-1175684716 * Try to improve CHANGELOG entry. * chore: update reframe spec link * Update go-delegated-routing dependency * Fix config error test * use new changelog format * Remove port conflict * go mod tidy * ProviderManyWrapper to ProviderMany * Update docs/changelogs/v0.14.md Co-authored-by: Adin Schmahmann <adin.schmahmann@gmail.com> Co-authored-by: Marcin Rataj <lidel@lidel.org> Co-authored-by: Adin Schmahmann <adin.schmahmann@gmail.com>
245 lines
5.6 KiB
Go
245 lines
5.6 KiB
Go
package config
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"io"
|
|
"time"
|
|
|
|
"github.com/ipfs/interface-go-ipfs-core/options"
|
|
"github.com/libp2p/go-libp2p-core/crypto"
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
|
)
|
|
|
|
func Init(out io.Writer, nBitsForKeypair int) (*Config, error) {
|
|
identity, err := CreateIdentity(out, []options.KeyGenerateOption{options.Key.Size(nBitsForKeypair)})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return InitWithIdentity(identity)
|
|
}
|
|
|
|
func InitWithIdentity(identity Identity) (*Config, error) {
|
|
bootstrapPeers, err := DefaultBootstrapPeers()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
datastore := DefaultDatastoreConfig()
|
|
|
|
conf := &Config{
|
|
API: API{
|
|
HTTPHeaders: map[string][]string{},
|
|
},
|
|
|
|
// setup the node's default addresses.
|
|
// NOTE: two swarm listen addrs, one tcp, one utp.
|
|
Addresses: addressesConfig(),
|
|
|
|
Datastore: datastore,
|
|
Bootstrap: BootstrapPeerStrings(bootstrapPeers),
|
|
Identity: identity,
|
|
Discovery: Discovery{
|
|
MDNS: MDNS{
|
|
Enabled: true,
|
|
},
|
|
},
|
|
|
|
Routing: Routing{
|
|
Type: NewOptionalString("dht"),
|
|
},
|
|
|
|
// setup the node mount points.
|
|
Mounts: Mounts{
|
|
IPFS: "/ipfs",
|
|
IPNS: "/ipns",
|
|
},
|
|
|
|
Ipns: Ipns{
|
|
ResolveCacheSize: 128,
|
|
},
|
|
|
|
Gateway: Gateway{
|
|
RootRedirect: "",
|
|
Writable: false,
|
|
NoFetch: false,
|
|
PathPrefixes: []string{},
|
|
HTTPHeaders: map[string][]string{
|
|
"Access-Control-Allow-Origin": {"*"},
|
|
"Access-Control-Allow-Methods": {"GET"},
|
|
"Access-Control-Allow-Headers": {"X-Requested-With", "Range", "User-Agent"},
|
|
},
|
|
APICommands: []string{},
|
|
},
|
|
Reprovider: Reprovider{
|
|
Interval: "12h",
|
|
Strategy: "all",
|
|
},
|
|
Swarm: SwarmConfig{
|
|
ConnMgr: ConnMgr{
|
|
LowWater: DefaultConnMgrLowWater,
|
|
HighWater: DefaultConnMgrHighWater,
|
|
GracePeriod: DefaultConnMgrGracePeriod.String(),
|
|
Type: "basic",
|
|
},
|
|
},
|
|
Pinning: Pinning{
|
|
RemoteServices: map[string]RemotePinningService{},
|
|
},
|
|
DNS: DNS{
|
|
Resolvers: map[string]string{},
|
|
},
|
|
Migration: Migration{
|
|
DownloadSources: []string{},
|
|
Keep: "",
|
|
},
|
|
}
|
|
|
|
return conf, nil
|
|
}
|
|
|
|
// DefaultConnMgrHighWater is the default value for the connection managers
|
|
// 'high water' mark
|
|
const DefaultConnMgrHighWater = 900
|
|
|
|
// DefaultConnMgrLowWater is the default value for the connection managers 'low
|
|
// water' mark
|
|
const DefaultConnMgrLowWater = 600
|
|
|
|
// DefaultConnMgrGracePeriod is the default value for the connection managers
|
|
// grace period
|
|
const DefaultConnMgrGracePeriod = time.Second * 20
|
|
|
|
func addressesConfig() Addresses {
|
|
return Addresses{
|
|
Swarm: []string{
|
|
"/ip4/0.0.0.0/tcp/4001",
|
|
"/ip6/::/tcp/4001",
|
|
"/ip4/0.0.0.0/udp/4001/quic",
|
|
"/ip6/::/udp/4001/quic",
|
|
},
|
|
Announce: []string{},
|
|
AppendAnnounce: []string{},
|
|
NoAnnounce: []string{},
|
|
API: Strings{"/ip4/127.0.0.1/tcp/5001"},
|
|
Gateway: Strings{"/ip4/127.0.0.1/tcp/8080"},
|
|
}
|
|
}
|
|
|
|
// DefaultDatastoreConfig is an internal function exported to aid in testing.
|
|
func DefaultDatastoreConfig() Datastore {
|
|
return Datastore{
|
|
StorageMax: "10GB",
|
|
StorageGCWatermark: 90, // 90%
|
|
GCPeriod: "1h",
|
|
BloomFilterSize: 0,
|
|
Spec: flatfsSpec(),
|
|
}
|
|
}
|
|
|
|
func badgerSpec() map[string]interface{} {
|
|
return map[string]interface{}{
|
|
"type": "measure",
|
|
"prefix": "badger.datastore",
|
|
"child": map[string]interface{}{
|
|
"type": "badgerds",
|
|
"path": "badgerds",
|
|
"syncWrites": false,
|
|
"truncate": true,
|
|
},
|
|
}
|
|
}
|
|
|
|
func flatfsSpec() map[string]interface{} {
|
|
return map[string]interface{}{
|
|
"type": "mount",
|
|
"mounts": []interface{}{
|
|
map[string]interface{}{
|
|
"mountpoint": "/blocks",
|
|
"type": "measure",
|
|
"prefix": "flatfs.datastore",
|
|
"child": map[string]interface{}{
|
|
"type": "flatfs",
|
|
"path": "blocks",
|
|
"sync": true,
|
|
"shardFunc": "/repo/flatfs/shard/v1/next-to-last/2",
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"mountpoint": "/",
|
|
"type": "measure",
|
|
"prefix": "leveldb.datastore",
|
|
"child": map[string]interface{}{
|
|
"type": "levelds",
|
|
"path": "datastore",
|
|
"compression": "none",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// CreateIdentity initializes a new identity.
|
|
func CreateIdentity(out io.Writer, opts []options.KeyGenerateOption) (Identity, error) {
|
|
// TODO guard higher up
|
|
ident := Identity{}
|
|
|
|
settings, err := options.KeyGenerateOptions(opts...)
|
|
if err != nil {
|
|
return ident, err
|
|
}
|
|
|
|
var sk crypto.PrivKey
|
|
var pk crypto.PubKey
|
|
|
|
switch settings.Algorithm {
|
|
case "rsa":
|
|
if settings.Size == -1 {
|
|
settings.Size = options.DefaultRSALen
|
|
}
|
|
|
|
fmt.Fprintf(out, "generating %d-bit RSA keypair...", settings.Size)
|
|
|
|
priv, pub, err := crypto.GenerateKeyPair(crypto.RSA, settings.Size)
|
|
if err != nil {
|
|
return ident, err
|
|
}
|
|
|
|
sk = priv
|
|
pk = pub
|
|
case "ed25519":
|
|
if settings.Size != -1 {
|
|
return ident, fmt.Errorf("number of key bits does not apply when using ed25519 keys")
|
|
}
|
|
fmt.Fprintf(out, "generating ED25519 keypair...")
|
|
priv, pub, err := crypto.GenerateEd25519Key(rand.Reader)
|
|
if err != nil {
|
|
return ident, err
|
|
}
|
|
|
|
sk = priv
|
|
pk = pub
|
|
default:
|
|
return ident, fmt.Errorf("unrecognized key type: %s", settings.Algorithm)
|
|
}
|
|
fmt.Fprintf(out, "done\n")
|
|
|
|
// currently storing key unencrypted. in the future we need to encrypt it.
|
|
// TODO(security)
|
|
skbytes, err := crypto.MarshalPrivateKey(sk)
|
|
if err != nil {
|
|
return ident, err
|
|
}
|
|
ident.PrivKey = base64.StdEncoding.EncodeToString(skbytes)
|
|
|
|
id, err := peer.IDFromPublicKey(pk)
|
|
if err != nil {
|
|
return ident, err
|
|
}
|
|
ident.PeerID = id.Pretty()
|
|
fmt.Fprintf(out, "peer identity: %s\n", ident.PeerID)
|
|
return ident, nil
|
|
}
|