mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-24 20:07:45 +08:00
Merge branch 'master' into merge-release-v0.21.0
This commit is contained in:
commit
0c890de400
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
|
||||
4
.github/workflows/docker-image.yml
vendored
4
.github/workflows/docker-image.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
LEGACY_IMAGE_NAME: ipfs/go-ipfs
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
@ -48,7 +48,7 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc
|
||||
with:
|
||||
username: ${{ vars.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
8
.github/workflows/gateway-conformance.yml
vendored
8
.github/workflows/gateway-conformance.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
steps:
|
||||
# 1. Download the gateway-conformance fixtures
|
||||
- name: Download gateway-conformance fixtures
|
||||
uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.1
|
||||
uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.2
|
||||
with:
|
||||
output: fixtures
|
||||
|
||||
@ -47,6 +47,7 @@ jobs:
|
||||
{
|
||||
"example.com": {
|
||||
"UseSubdomains": true,
|
||||
"InlineDNSLink": true,
|
||||
"Paths": ["/ipfs", "/ipns"]
|
||||
},
|
||||
"localhost": {
|
||||
@ -76,7 +77,8 @@ jobs:
|
||||
|
||||
# Import dnslink records
|
||||
# the IPFS_NS_MAP env will be used by the daemon
|
||||
export IPFS_NS_MAP=$(cat ./fixtures/dnslinks.json | jq -r 'to_entries | map("\(.key).example.com:\(.value)") | join(",")')
|
||||
export IPFS_NS_MAP=$(cat "./fixtures/dnslinks.json" | jq -r '.subdomains | to_entries | map("\(.key).example.com:\(.value)") | join(",")')
|
||||
export IPFS_NS_MAP="$(cat "./fixtures/dnslinks.json" | jq -r '.domains | to_entries | map("\(.key):\(.value)") | join(",")'),${IPFS_NS_MAP}"
|
||||
echo "IPFS_NS_MAP=${IPFS_NS_MAP}" >> $GITHUB_ENV
|
||||
|
||||
# 5. Start the kubo-gateway
|
||||
@ -87,7 +89,7 @@ jobs:
|
||||
|
||||
# 6. Run the gateway-conformance tests
|
||||
- name: Run gateway-conformance tests
|
||||
uses: ipfs/gateway-conformance/.github/actions/test@v0.1
|
||||
uses: ipfs/gateway-conformance/.github/actions/test@v0.2
|
||||
with:
|
||||
gateway-url: http://127.0.0.1:8080
|
||||
json: output.json
|
||||
|
||||
2
.github/workflows/golang-analysis.yml
vendored
2
.github/workflows/golang-analysis.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions/setup-go@v2
|
||||
|
||||
6
.github/workflows/stale.yml
vendored
6
.github/workflows/stale.yml
vendored
@ -2,7 +2,11 @@ name: Close and mark stale issue
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
6
.github/workflows/sync-release-assets.yml
vendored
6
.github/workflows/sync-release-assets.yml
vendored
@ -26,14 +26,14 @@ jobs:
|
||||
with:
|
||||
node-version: 14
|
||||
- name: Sync the latest 5 github releases
|
||||
uses: actions/github-script@v4
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs').promises
|
||||
const max_synced = 5
|
||||
|
||||
// fetch github releases
|
||||
resp = await github.repos.listReleases({
|
||||
resp = await github.rest.repos.listReleases({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
page: 1,
|
||||
@ -116,7 +116,7 @@ jobs:
|
||||
}
|
||||
|
||||
console.log("uploading", file, "to github release", release.tag_name)
|
||||
const uploadReleaseAsset = async (file) => github.repos.uploadReleaseAsset({
|
||||
const uploadReleaseAsset = async (file) => github.rest.repos.uploadReleaseAsset({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
release_id: release.id,
|
||||
|
||||
@ -10,29 +10,20 @@ import (
|
||||
caopts "github.com/ipfs/boxo/coreiface/options"
|
||||
nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
|
||||
"github.com/ipfs/boxo/coreiface/path"
|
||||
"github.com/ipfs/boxo/ipns"
|
||||
)
|
||||
|
||||
type NameAPI HttpApi
|
||||
|
||||
type ipnsEntry struct {
|
||||
JName string `json:"Name"`
|
||||
JValue string `json:"Value"`
|
||||
|
||||
path path.Path
|
||||
Name string `json:"Name"`
|
||||
Value string `json:"Value"`
|
||||
}
|
||||
|
||||
func (e *ipnsEntry) Name() string {
|
||||
return e.JName
|
||||
}
|
||||
|
||||
func (e *ipnsEntry) Value() path.Path {
|
||||
return e.path
|
||||
}
|
||||
|
||||
func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.NamePublishOption) (iface.IpnsEntry, error) {
|
||||
func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.NamePublishOption) (ipns.Name, error) {
|
||||
options, err := caopts.NamePublishOptions(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ipns.Name{}, err
|
||||
}
|
||||
|
||||
req := api.core().Request("name/publish", p.String()).
|
||||
@ -47,10 +38,9 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam
|
||||
|
||||
var out ipnsEntry
|
||||
if err := req.Exec(ctx, &out); err != nil {
|
||||
return nil, err
|
||||
return ipns.Name{}, err
|
||||
}
|
||||
out.path = path.New(out.JValue)
|
||||
return &out, out.path.IsValid()
|
||||
return ipns.NameFromString(out.Name)
|
||||
}
|
||||
|
||||
func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.NameResolveOption) (<-chan iface.IpnsResult, error) {
|
||||
|
||||
@ -28,7 +28,7 @@ type Router struct {
|
||||
Type RouterType
|
||||
|
||||
// Parameters are extra configuration that this router might need.
|
||||
// A common one for reframe router is "Endpoint".
|
||||
// A common one for HTTP router is "Endpoint".
|
||||
Parameters interface{}
|
||||
}
|
||||
|
||||
@ -81,8 +81,6 @@ func (r *RouterParser) UnmarshalJSON(b []byte) error {
|
||||
switch out.Type {
|
||||
case RouterTypeHTTP:
|
||||
p = &HTTPRouterParams{}
|
||||
case RouterTypeReframe:
|
||||
p = &ReframeRouterParams{}
|
||||
case RouterTypeDHT:
|
||||
p = &DHTRouterParams{}
|
||||
case RouterTypeSequential:
|
||||
@ -106,7 +104,6 @@ func (r *RouterParser) UnmarshalJSON(b []byte) error {
|
||||
type RouterType string
|
||||
|
||||
const (
|
||||
RouterTypeReframe RouterType = "reframe" // More info here: https://github.com/ipfs/specs/tree/main/reframe . Actually deprecated.
|
||||
RouterTypeHTTP RouterType = "http" // HTTP JSON API for delegated routing systems (IPIP-337).
|
||||
RouterTypeDHT RouterType = "dht" // DHT router.
|
||||
RouterTypeSequential RouterType = "sequential" // Router helper to execute several routers sequentially.
|
||||
@ -133,12 +130,6 @@ const (
|
||||
|
||||
var MethodNameList = []MethodName{MethodNameProvide, MethodNameFindPeers, MethodNameFindProviders, MethodNameGetIPNS, MethodNamePutIPNS}
|
||||
|
||||
type ReframeRouterParams struct {
|
||||
// Endpoint is the URL where the routing implementation will point to get the information.
|
||||
// Usually used for reframe Routers.
|
||||
Endpoint string
|
||||
}
|
||||
|
||||
type HTTPRouterParams struct {
|
||||
// Endpoint is the URL where the routing implementation will point to get the information.
|
||||
Endpoint string
|
||||
|
||||
@ -23,12 +23,6 @@ func TestRouterParameters(t *testing.T) {
|
||||
PublicIPNetwork: false,
|
||||
},
|
||||
}},
|
||||
"router-reframe": {Router{
|
||||
Type: RouterTypeReframe,
|
||||
Parameters: ReframeRouterParams{
|
||||
Endpoint: "reframe-endpoint",
|
||||
},
|
||||
}},
|
||||
"router-parallel": {Router{
|
||||
Type: RouterTypeParallel,
|
||||
Parameters: ComposableRouterParams{
|
||||
@ -39,7 +33,7 @@ func TestRouterParameters(t *testing.T) {
|
||||
IgnoreErrors: true,
|
||||
},
|
||||
{
|
||||
RouterName: "router-reframe",
|
||||
RouterName: "router-dht",
|
||||
Timeout: Duration{10 * time.Second},
|
||||
IgnoreErrors: false,
|
||||
ExecuteAfter: &OptionalDuration{&sec},
|
||||
@ -58,7 +52,7 @@ func TestRouterParameters(t *testing.T) {
|
||||
IgnoreErrors: true,
|
||||
},
|
||||
{
|
||||
RouterName: "router-reframe",
|
||||
RouterName: "router-dht",
|
||||
Timeout: Duration{10 * time.Second},
|
||||
IgnoreErrors: false,
|
||||
},
|
||||
@ -69,7 +63,7 @@ func TestRouterParameters(t *testing.T) {
|
||||
},
|
||||
Methods: Methods{
|
||||
MethodNameFindPeers: {
|
||||
RouterName: "router-reframe",
|
||||
RouterName: "router-dht",
|
||||
},
|
||||
MethodNameFindProviders: {
|
||||
RouterName: "router-dht",
|
||||
@ -99,9 +93,6 @@ func TestRouterParameters(t *testing.T) {
|
||||
dhtp := r2.Routers["router-dht"].Parameters
|
||||
require.IsType(&DHTRouterParams{}, dhtp)
|
||||
|
||||
rp := r2.Routers["router-reframe"].Parameters
|
||||
require.IsType(&ReframeRouterParams{}, rp)
|
||||
|
||||
sp := r2.Routers["router-sequential"].Parameters
|
||||
require.IsType(&ComposableRouterParams{}, sp)
|
||||
|
||||
@ -109,68 +100,24 @@ func TestRouterParameters(t *testing.T) {
|
||||
require.IsType(&ComposableRouterParams{}, pp)
|
||||
}
|
||||
|
||||
func TestRouterMissingParameters(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
r := Routing{
|
||||
Type: NewOptionalString("custom"),
|
||||
Routers: map[string]RouterParser{
|
||||
"router-wrong-reframe": {Router{
|
||||
Type: RouterTypeReframe,
|
||||
Parameters: DHTRouterParams{
|
||||
Mode: "auto",
|
||||
AcceleratedDHTClient: true,
|
||||
PublicIPNetwork: false,
|
||||
},
|
||||
}},
|
||||
},
|
||||
Methods: Methods{
|
||||
MethodNameFindPeers: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
},
|
||||
MethodNameFindProviders: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
},
|
||||
MethodNameGetIPNS: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
},
|
||||
MethodNameProvide: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
},
|
||||
MethodNamePutIPNS: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
out, err := json.Marshal(r)
|
||||
require.NoError(err)
|
||||
|
||||
r2 := &Routing{}
|
||||
|
||||
err = json.Unmarshal(out, r2)
|
||||
require.NoError(err)
|
||||
require.Empty(r2.Routers["router-wrong-reframe"].Parameters.(*ReframeRouterParams).Endpoint)
|
||||
}
|
||||
|
||||
func TestMethods(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
methodsOK := Methods{
|
||||
MethodNameFindPeers: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
RouterName: "router-wrong",
|
||||
},
|
||||
MethodNameFindProviders: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
RouterName: "router-wrong",
|
||||
},
|
||||
MethodNameGetIPNS: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
RouterName: "router-wrong",
|
||||
},
|
||||
MethodNameProvide: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
RouterName: "router-wrong",
|
||||
},
|
||||
MethodNamePutIPNS: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
RouterName: "router-wrong",
|
||||
},
|
||||
}
|
||||
|
||||
@ -178,16 +125,16 @@ func TestMethods(t *testing.T) {
|
||||
|
||||
methodsMissing := Methods{
|
||||
MethodNameFindPeers: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
RouterName: "router-wrong",
|
||||
},
|
||||
MethodNameGetIPNS: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
RouterName: "router-wrong",
|
||||
},
|
||||
MethodNameProvide: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
RouterName: "router-wrong",
|
||||
},
|
||||
MethodNamePutIPNS: {
|
||||
RouterName: "router-wrong-reframe",
|
||||
RouterName: "router-wrong",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@ -15,8 +15,8 @@ import (
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
"github.com/ipfs/kubo/core/commands/cmdenv"
|
||||
|
||||
gocar "github.com/ipfs/boxo/ipld/car"
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
gocar "github.com/ipld/go-car"
|
||||
selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
|
||||
)
|
||||
|
||||
|
||||
@ -7,12 +7,12 @@ import (
|
||||
|
||||
"github.com/ipfs/boxo/coreiface/options"
|
||||
"github.com/ipfs/boxo/files"
|
||||
gocarv2 "github.com/ipfs/boxo/ipld/car/v2"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
ipldlegacy "github.com/ipfs/go-ipld-legacy"
|
||||
gocarv2 "github.com/ipld/go-car/v2"
|
||||
|
||||
"github.com/ipfs/kubo/core/commands/cmdenv"
|
||||
"github.com/ipfs/kubo/core/commands/cmdutils"
|
||||
|
||||
@ -12,7 +12,7 @@ import (
|
||||
func TestKeyTranslation(t *testing.T) {
|
||||
pid := test.RandPeerIDFatal(t)
|
||||
pkname := namesys.PkKeyForID(pid)
|
||||
ipnsname := ipns.RecordKey(pid)
|
||||
ipnsname := ipns.NameFromPeer(pid).RoutingKey()
|
||||
|
||||
pkk, err := escapeDhtKey("/pk/" + pid.Pretty())
|
||||
if err != nil {
|
||||
@ -28,7 +28,7 @@ func TestKeyTranslation(t *testing.T) {
|
||||
t.Fatal("keys didn't match!")
|
||||
}
|
||||
|
||||
if ipnsk != ipnsname {
|
||||
if ipnsk != string(ipnsname) {
|
||||
t.Fatal("keys didn't match!")
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,23 +2,18 @@ package name
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/ipfs/boxo/ipns"
|
||||
ipns_pb "github.com/ipfs/boxo/ipns/pb"
|
||||
"github.com/ipfs/boxo/path"
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
|
||||
"github.com/ipld/go-ipld-prime"
|
||||
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
||||
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
mbase "github.com/multiformats/go-multibase"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type IpnsEntry struct {
|
||||
@ -84,28 +79,27 @@ Resolve the value of a dnslink:
|
||||
}
|
||||
|
||||
type IpnsInspectValidation struct {
|
||||
Valid bool
|
||||
Reason string
|
||||
PublicKey peer.ID
|
||||
Valid bool
|
||||
Reason string
|
||||
Name string
|
||||
}
|
||||
|
||||
// IpnsInspectEntry contains the deserialized values from an IPNS Entry:
|
||||
// https://github.com/ipfs/specs/blob/main/ipns/IPNS.md#record-serialization-format
|
||||
type IpnsInspectEntry struct {
|
||||
Value string
|
||||
ValidityType *ipns_pb.IpnsEntry_ValidityType
|
||||
Value *path.Path
|
||||
ValidityType *ipns.ValidityType
|
||||
Validity *time.Time
|
||||
Sequence uint64
|
||||
TTL *uint64
|
||||
PublicKey string
|
||||
SignatureV1 string
|
||||
SignatureV2 string
|
||||
Data interface{}
|
||||
Sequence *uint64
|
||||
TTL *time.Duration
|
||||
}
|
||||
|
||||
type IpnsInspectResult struct {
|
||||
Entry IpnsInspectEntry
|
||||
Validation *IpnsInspectValidation
|
||||
Entry IpnsInspectEntry
|
||||
PbSize int
|
||||
SignatureType string
|
||||
HexDump string
|
||||
Validation *IpnsInspectValidation
|
||||
}
|
||||
|
||||
var IpnsInspectCmd = &cmds.Command{
|
||||
@ -136,6 +130,7 @@ Passing --verify will verify signature against provided public key.
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.StringOption("verify", "CID of the public IPNS key to validate against."),
|
||||
cmds.BoolOption("dump", "Include a full hex dump of the raw Protobuf record.").WithDefault(true),
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
file, err := cmdenv.GetFileArg(req.Files.Entries())
|
||||
@ -151,71 +146,62 @@ Passing --verify will verify signature against provided public key.
|
||||
return err
|
||||
}
|
||||
|
||||
var entry ipns_pb.IpnsEntry
|
||||
err = proto.Unmarshal(b.Bytes(), &entry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encoder, err := mbase.EncoderByName("base64")
|
||||
rec, err := ipns.UnmarshalRecord(b.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result := &IpnsInspectResult{
|
||||
Entry: IpnsInspectEntry{
|
||||
Value: string(entry.Value),
|
||||
ValidityType: entry.ValidityType,
|
||||
Sequence: *entry.Sequence,
|
||||
TTL: entry.Ttl,
|
||||
PublicKey: encoder.Encode(entry.PubKey),
|
||||
SignatureV1: encoder.Encode(entry.SignatureV1),
|
||||
SignatureV2: encoder.Encode(entry.SignatureV2),
|
||||
Data: nil,
|
||||
},
|
||||
Entry: IpnsInspectEntry{},
|
||||
}
|
||||
|
||||
if len(entry.Data) != 0 {
|
||||
// This is hacky. The variable node (datamodel.Node) doesn't directly marshal
|
||||
// to JSON. Therefore, we need to first decode from DAG-CBOR, then encode in
|
||||
// DAG-JSON and finally unmarshal it from JSON. Since DAG-JSON is a subset
|
||||
// of JSON, that should work. Then, we can store the final value in the
|
||||
// result.Entry.Data for further inspection.
|
||||
node, err := ipld.Decode(entry.Data, dagcbor.Decode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
err = dagjson.Encode(node, &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(buf.Bytes(), &result.Entry.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Best effort to get the fields. Show everything we can.
|
||||
if v, err := rec.Value(); err == nil {
|
||||
result.Entry.Value = &v
|
||||
}
|
||||
|
||||
validity, err := ipns.GetEOL(&entry)
|
||||
if err == nil {
|
||||
result.Entry.Validity = &validity
|
||||
if v, err := rec.ValidityType(); err == nil {
|
||||
result.Entry.ValidityType = &v
|
||||
}
|
||||
|
||||
verify, ok := req.Options["verify"].(string)
|
||||
if ok {
|
||||
key := strings.TrimPrefix(verify, "/ipns/")
|
||||
id, err := peer.Decode(key)
|
||||
if v, err := rec.Validity(); err == nil {
|
||||
result.Entry.Validity = &v
|
||||
}
|
||||
|
||||
if v, err := rec.Sequence(); err == nil {
|
||||
result.Entry.Sequence = &v
|
||||
}
|
||||
|
||||
if v, err := rec.TTL(); err == nil {
|
||||
result.Entry.TTL = &v
|
||||
}
|
||||
|
||||
// Here we need the raw protobuf just to decide the version.
|
||||
var pbRecord ipns_pb.IpnsRecord
|
||||
err = proto.Unmarshal(b.Bytes(), &pbRecord)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(pbRecord.SignatureV1) != 0 || len(pbRecord.Value) != 0 {
|
||||
result.SignatureType = "V1+V2"
|
||||
} else if pbRecord.Data != nil {
|
||||
result.SignatureType = "V2"
|
||||
} else {
|
||||
result.SignatureType = "Unknown"
|
||||
}
|
||||
result.PbSize = proto.Size(&pbRecord)
|
||||
|
||||
if verify, ok := req.Options["verify"].(string); ok {
|
||||
name, err := ipns.NameFromString(verify)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result.Validation = &IpnsInspectValidation{
|
||||
PublicKey: id,
|
||||
Name: name.String(),
|
||||
}
|
||||
|
||||
err = ipns.ValidateWithPeerID(id, &entry)
|
||||
err = ipns.ValidateWithName(rec, name)
|
||||
if err == nil {
|
||||
result.Validation.Valid = true
|
||||
} else {
|
||||
@ -223,6 +209,10 @@ Passing --verify will verify signature against provided public key.
|
||||
}
|
||||
}
|
||||
|
||||
if dump, ok := req.Options["dump"].(bool); ok && dump {
|
||||
result.HexDump = hex.Dump(b.Bytes())
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, result)
|
||||
},
|
||||
Type: IpnsInspectResult{},
|
||||
@ -231,24 +221,28 @@ Passing --verify will verify signature against provided public key.
|
||||
tw := tabwriter.NewWriter(w, 0, 0, 1, ' ', 0)
|
||||
defer tw.Flush()
|
||||
|
||||
fmt.Fprintf(tw, "Value:\t%q\n", string(out.Entry.Value))
|
||||
fmt.Fprintf(tw, "Validity Type:\t%q\n", out.Entry.ValidityType)
|
||||
if out.Entry.Validity != nil {
|
||||
fmt.Fprintf(tw, "Validity:\t%s\n", out.Entry.Validity.Format(time.RFC3339Nano))
|
||||
if out.Entry.Value != nil {
|
||||
fmt.Fprintf(tw, "Value:\t%q\n", out.Entry.Value.String())
|
||||
}
|
||||
fmt.Fprintf(tw, "Sequence:\t%d\n", out.Entry.Sequence)
|
||||
if out.Entry.TTL != nil {
|
||||
fmt.Fprintf(tw, "TTL:\t%d\n", *out.Entry.TTL)
|
||||
}
|
||||
fmt.Fprintf(tw, "PublicKey:\t%q\n", out.Entry.PublicKey)
|
||||
fmt.Fprintf(tw, "Signature V1:\t%q\n", out.Entry.SignatureV1)
|
||||
fmt.Fprintf(tw, "Signature V2:\t%q\n", out.Entry.SignatureV2)
|
||||
|
||||
data, err := json.Marshal(out.Entry.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
if out.Entry.ValidityType != nil {
|
||||
fmt.Fprintf(tw, "Validity Type:\t%q\n", *out.Entry.ValidityType)
|
||||
}
|
||||
fmt.Fprintf(tw, "Data:\t%s\n", string(data))
|
||||
|
||||
if out.Entry.Validity != nil {
|
||||
fmt.Fprintf(tw, "Validity:\t%q\n", out.Entry.Validity.Format(time.RFC3339Nano))
|
||||
}
|
||||
|
||||
if out.Entry.Sequence != nil {
|
||||
fmt.Fprintf(tw, "Sequence:\t%d\n", *out.Entry.Sequence)
|
||||
}
|
||||
|
||||
if out.Entry.TTL != nil {
|
||||
fmt.Fprintf(tw, "TTL:\t%s\n", out.Entry.TTL.String())
|
||||
}
|
||||
|
||||
fmt.Fprintf(tw, "Protobuf Size:\t%d\n", out.PbSize)
|
||||
fmt.Fprintf(tw, "Signature Type:\t%s\n", out.SignatureType)
|
||||
|
||||
if out.Validation == nil {
|
||||
tw.Flush()
|
||||
@ -261,7 +255,14 @@ Passing --verify will verify signature against provided public key.
|
||||
if out.Validation.Reason != "" {
|
||||
fmt.Fprintf(tw, "\tReason:\t%s\n", out.Validation.Reason)
|
||||
}
|
||||
fmt.Fprintf(tw, "\tPublicKey:\t%s\n", out.Validation.PublicKey)
|
||||
fmt.Fprintf(tw, "\tName:\t%s\n", out.Validation.Name)
|
||||
}
|
||||
|
||||
if out.HexDump != "" {
|
||||
tw.Flush()
|
||||
|
||||
fmt.Fprintf(w, "\nHex Dump:\n")
|
||||
fmt.Fprintf(w, out.HexDump)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@ -13,7 +13,6 @@ import (
|
||||
path "github.com/ipfs/boxo/coreiface/path"
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
ke "github.com/ipfs/kubo/core/commands/keyencode"
|
||||
peer "github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -28,6 +27,7 @@ const (
|
||||
ttlOptionName = "ttl"
|
||||
keyOptionName = "key"
|
||||
quieterOptionName = "quieter"
|
||||
v1compatOptionName = "v1compat"
|
||||
)
|
||||
|
||||
var PublishCmd = &cmds.Command{
|
||||
@ -83,6 +83,7 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
cmds.StringOption(ttlOptionName, "Time duration this record should be cached for. Uses the same syntax as the lifetime option. (caution: experimental)"),
|
||||
cmds.StringOption(keyOptionName, "k", "Name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'.").WithDefault("self"),
|
||||
cmds.BoolOption(quieterOptionName, "Q", "Write only final hash."),
|
||||
cmds.BoolOption(v1compatOptionName, "Produce a backward-compatible IPNS Record by including fields for both V1 and V2 signatures.").WithDefault(true),
|
||||
ke.OptionIPNSBase,
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
@ -90,12 +91,9 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
allowOffline, _ := req.Options[allowOfflineOptionName].(bool)
|
||||
compatibleWithV1, _ := req.Options[v1compatOptionName].(bool)
|
||||
kname, _ := req.Options[keyOptionName].(string)
|
||||
|
||||
validTimeOpt, _ := req.Options[lifeTimeOptionName].(string)
|
||||
@ -108,6 +106,7 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
options.Name.AllowOffline(allowOffline),
|
||||
options.Name.Key(kname),
|
||||
options.Name.ValidTime(validTime),
|
||||
options.Name.CompatibleWithV1(compatibleWithV1),
|
||||
}
|
||||
|
||||
if ttl, found := req.Options[ttlOptionName].(string); found {
|
||||
@ -128,7 +127,7 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
}
|
||||
}
|
||||
|
||||
out, err := api.Name().Publish(req.Context, p, opts...)
|
||||
name, err := api.Name().Publish(req.Context, p, opts...)
|
||||
if err != nil {
|
||||
if err == iface.ErrOffline {
|
||||
err = errAllowOffline
|
||||
@ -136,15 +135,9 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
return err
|
||||
}
|
||||
|
||||
// parse path, extract cid, re-base cid, reconstruct path
|
||||
pid, err := peer.Decode(out.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &IpnsEntry{
|
||||
Name: keyEnc.FormatID(pid),
|
||||
Value: out.Value().String(),
|
||||
Name: name.String(),
|
||||
Value: p.String(),
|
||||
})
|
||||
},
|
||||
Encoders: cmds.EncoderMap{
|
||||
|
||||
@ -1,28 +1,14 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http/httptest"
|
||||
"path"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
context "context"
|
||||
|
||||
"github.com/ipfs/boxo/ipns"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-delegated-routing/client"
|
||||
"github.com/ipfs/kubo/core/node/libp2p"
|
||||
"github.com/ipfs/kubo/repo"
|
||||
"github.com/libp2p/go-libp2p/core/crypto"
|
||||
peer "github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
datastore "github.com/ipfs/go-datastore"
|
||||
syncds "github.com/ipfs/go-datastore/sync"
|
||||
drs "github.com/ipfs/go-delegated-routing/server"
|
||||
config "github.com/ipfs/kubo/config"
|
||||
)
|
||||
|
||||
@ -79,285 +65,3 @@ var testIdentity = config.Identity{
|
||||
PeerID: "QmNgdzLieYi8tgfo2WfTUzNVH5hQK9oAYGVf6dxN12NrHt",
|
||||
PrivKey: "CAASrRIwggkpAgEAAoICAQCwt67GTUQ8nlJhks6CgbLKOx7F5tl1r9zF4m3TUrG3Pe8h64vi+ILDRFd7QJxaJ/n8ux9RUDoxLjzftL4uTdtv5UXl2vaufCc/C0bhCRvDhuWPhVsD75/DZPbwLsepxocwVWTyq7/ZHsCfuWdoh/KNczfy+Gn33gVQbHCnip/uhTVxT7ARTiv8Qa3d7qmmxsR+1zdL/IRO0mic/iojcb3Oc/PRnYBTiAZFbZdUEit/99tnfSjMDg02wRayZaT5ikxa6gBTMZ16Yvienq7RwSELzMQq2jFA4i/TdiGhS9uKywltiN2LrNDBcQJSN02pK12DKoiIy+wuOCRgs2NTQEhU2sXCk091v7giTTOpFX2ij9ghmiRfoSiBFPJA5RGwiH6ansCHtWKY1K8BS5UORM0o3dYk87mTnKbCsdz4bYnGtOWafujYwzueGx8r+IWiys80IPQKDeehnLW6RgoyjszKgL/2XTyP54xMLSW+Qb3BPgDcPaPO0hmop1hW9upStxKsefW2A2d46Ds4HEpJEry7PkS5M4gKL/zCKHuxuXVk14+fZQ1rstMuvKjrekpAC2aVIKMI9VRA3awtnje8HImQMdj+r+bPmv0N8rTTr3eS4J8Yl7k12i95LLfK+fWnmUh22oTNzkRlaiERQrUDyE4XNCtJc0xs1oe1yXGqazCIAQIDAQABAoICAQCk1N/ftahlRmOfAXk//8wNl7FvdJD3le6+YSKBj0uWmN1ZbUSQk64chr12iGCOM2WY180xYjy1LOS44PTXaeW5bEiTSnb3b3SH+HPHaWCNM2EiSogHltYVQjKW+3tfH39vlOdQ9uQ+l9Gh6iTLOqsCRyszpYPqIBwi1NMLY2Ej8PpVU7ftnFWouHZ9YKS7nAEiMoowhTu/7cCIVwZlAy3AySTuKxPMVj9LORqC32PVvBHZaMPJ+X1Xyijqg6aq39WyoztkXg3+Xxx5j5eOrK6vO/Lp6ZUxaQilHDXoJkKEJjgIBDZpluss08UPfOgiWAGkW+L4fgUxY0qDLDAEMhyEBAn6KOKVL1JhGTX6GjhWziI94bddSpHKYOEIDzUy4H8BXnKhtnyQV6ELS65C2hj9D0IMBTj7edCF1poJy0QfdK0cuXgMvxHLeUO5uc2YWfbNosvKxqygB9rToy4b22YvNwsZUXsTY6Jt+p9V2OgXSKfB5VPeRbjTJL6xqvvUJpQytmII/C9JmSDUtCbYceHj6X9jgigLk20VV6nWHqCTj3utXD6NPAjoycVpLKDlnWEgfVELDIk0gobxUqqSm3jTPEKRPJgxkgPxbwxYumtw++1UY2y35w3WRDc2xYPaWKBCQeZy+mL6ByXp9bWlNvxS3Knb6oZp36/ovGnf2pGvdQKCAQEAyKpipz2lIUySDyE0avVWAmQb2tWGKXALPohzj7AwkcfEg2GuwoC6GyVE2sTJD1HRazIjOKn3yQORg2uOPeG7sx7EKHxSxCKDrbPawkvLCq8JYSy9TLvhqKUVVGYPqMBzu2POSLEA81QXas+aYjKOFWA2Zrjq26zV9ey3+6Lc6WULePgRQybU8+RHJc6fdjUCCfUxgOrUO2IQOuTJ+FsDpVnrMUGlokmWn23OjL4qTL9wGDnWGUs2pjSzNbj3qA0d8iqaiMUyHX/D/VS0wpeT1osNBSm8suvSibYBn+7wbIApbwXUxZaxMv2OHGz3empae4ckvNZs7r8wsI9UwFt8mwKCAQEA4XK6gZkv9t+3YCcSPw2ensLvL/xU7i2bkC9tfTGdjnQfzZXIf5KNdVuj/SerOl2S1s45NMs3ysJbADwRb4ahElD/V71nGzV8fpFTitC20ro9fuX4J0+twmBolHqeH9pmeGTjAeL1rvt6vxs4FkeG/yNft7GdXpXTtEGaObn8Mt0tPY+aB3UnKrnCQoQAlPyGHFrVRX0UEcp6wyyNGhJCNKeNOvqCHTFObhbhO+KWpWSN0MkVHnqaIBnIn1Te8FtvP/iTwXGnKc0YXJUG6+LM6LmOguW6tg8ZqiQeYyyR+e9eCFH4csLzkrTl1GxCxwEsoSLIMm7UDcjttW6tYEghkwKCAQEAmeCO5lCPYImnN5Lu71ZTLmI2OgmjaANTnBBnDbi+hgv61gUCToUIMejSdDCTPfwv61P3TmyIZs0luPGxkiKYHTNqmOE9Vspgz8Mr7fLRMNApESuNvloVIY32XVImj/GEzh4rAfM6F15U1sN8T/EUo6+0B/Glp+9R49QzAfRSE2g48/rGwgf1JVHYfVWFUtAzUA+GdqWdOixo5cCsYJbqpNHfWVZN/bUQnBFIYwUwysnC29D+LUdQEQQ4qOm+gFAOtrWU62zMkXJ4iLt8Ify6kbrvsRXgbhQIzzGS7WH9XDarj0eZciuslr15TLMC1Azadf+cXHLR9gMHA13mT9vYIQKCAQA/DjGv8cKCkAvf7s2hqROGYAs6Jp8yhrsN1tYOwAPLRhtnCs+rLrg17M2vDptLlcRuI/vIElamdTmylRpjUQpX7yObzLO73nfVhpwRJVMdGU394iBIDncQ+JoHfUwgqJskbUM40dvZdyjbrqc/Q/4z+hbZb+oN/GXb8sVKBATPzSDMKQ/xqgisYIw+wmDPStnPsHAaIWOtni47zIgilJzD0WEk78/YjmPbUrboYvWziK5JiRRJFA1rkQqV1c0M+OXixIm+/yS8AksgCeaHr0WUieGcJtjT9uE8vyFop5ykhRiNxy9wGaq6i7IEecsrkd6DqxDHWkwhFuO1bSE83q/VAoIBAEA+RX1i/SUi08p71ggUi9WFMqXmzELp1L3hiEjOc2AklHk2rPxsaTh9+G95BvjhP7fRa/Yga+yDtYuyjO99nedStdNNSg03aPXILl9gs3r2dPiQKUEXZJ3FrH6tkils/8BlpOIRfbkszrdZIKTO9GCdLWQ30dQITDACs8zV/1GFGrHFrqnnMe/NpIFHWNZJ0/WZMi8wgWO6Ik8jHEpQtVXRiXLqy7U6hk170pa4GHOzvftfPElOZZjy9qn7KjdAQqy6spIrAE94OEL+fBgbHQZGLpuTlj6w6YGbMtPU8uo7sXKoc6WOCb68JWft3tejGLDa1946HAWqVM9B/UcneNc=",
|
||||
}
|
||||
|
||||
var errNotSupported = errors.New("method not supported")
|
||||
|
||||
func TestDelegatedRoutingSingle(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
pID1, priv1, err := GeneratePeerID()
|
||||
require.NoError(err)
|
||||
|
||||
pID2, _, err := GeneratePeerID()
|
||||
require.NoError(err)
|
||||
|
||||
theID := path.Join("/ipns", string(pID1))
|
||||
theErrorID := path.Join("/ipns", string(pID2))
|
||||
|
||||
d := &delegatedRoutingService{
|
||||
goodPeerID: pID1,
|
||||
badPeerID: pID2,
|
||||
pk1: priv1,
|
||||
}
|
||||
|
||||
url := StartRoutingServer(t, d)
|
||||
n := GetNode(t, url)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
v, err := n.Routing.GetValue(ctx, theID)
|
||||
require.NoError(err)
|
||||
require.NotNil(v)
|
||||
require.Contains(string(v), "RECORD FROM SERVICE 0")
|
||||
|
||||
v, err = n.Routing.GetValue(ctx, theErrorID)
|
||||
require.Nil(v)
|
||||
require.Error(err)
|
||||
|
||||
err = n.Routing.PutValue(ctx, theID, v)
|
||||
require.NoError(err)
|
||||
|
||||
}
|
||||
|
||||
func TestDelegatedRoutingMulti(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
pID1, priv1, err := GeneratePeerID()
|
||||
require.NoError(err)
|
||||
|
||||
pID2, priv2, err := GeneratePeerID()
|
||||
require.NoError(err)
|
||||
|
||||
theID1 := path.Join("/ipns", string(pID1))
|
||||
theID2 := path.Join("/ipns", string(pID2))
|
||||
|
||||
d1 := &delegatedRoutingService{
|
||||
goodPeerID: pID1,
|
||||
badPeerID: pID2,
|
||||
pk1: priv1,
|
||||
serviceID: 1,
|
||||
}
|
||||
|
||||
url1 := StartRoutingServer(t, d1)
|
||||
|
||||
d2 := &delegatedRoutingService{
|
||||
goodPeerID: pID2,
|
||||
badPeerID: pID1,
|
||||
pk1: priv2,
|
||||
serviceID: 2,
|
||||
}
|
||||
|
||||
url2 := StartRoutingServer(t, d2)
|
||||
|
||||
n := GetNode(t, url1, url2)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
v, err := n.Routing.GetValue(ctx, theID1)
|
||||
require.NoError(err)
|
||||
require.NotNil(v)
|
||||
require.Contains(string(v), "RECORD FROM SERVICE 1")
|
||||
|
||||
v, err = n.Routing.GetValue(ctx, theID2)
|
||||
require.NoError(err)
|
||||
require.NotNil(v)
|
||||
require.Contains(string(v), "RECORD FROM SERVICE 2")
|
||||
}
|
||||
|
||||
func StartRoutingServer(t *testing.T, d drs.DelegatedRoutingService) string {
|
||||
t.Helper()
|
||||
|
||||
f := drs.DelegatedRoutingAsyncHandler(d)
|
||||
svr := httptest.NewServer(f)
|
||||
t.Cleanup(func() {
|
||||
svr.Close()
|
||||
})
|
||||
|
||||
return svr.URL
|
||||
}
|
||||
|
||||
func GetNode(t *testing.T, reframeURLs ...string) *IpfsNode {
|
||||
t.Helper()
|
||||
|
||||
routers := make(config.Routers)
|
||||
var routerNames []string
|
||||
for i, ru := range reframeURLs {
|
||||
rn := fmt.Sprintf("reframe-%d", i)
|
||||
routerNames = append(routerNames, rn)
|
||||
routers[rn] =
|
||||
config.RouterParser{
|
||||
Router: config.Router{
|
||||
Type: config.RouterTypeReframe,
|
||||
Parameters: &config.ReframeRouterParams{
|
||||
Endpoint: ru,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var crs []config.ConfigRouter
|
||||
for _, rn := range routerNames {
|
||||
crs = append(crs, config.ConfigRouter{
|
||||
RouterName: rn,
|
||||
IgnoreErrors: true,
|
||||
Timeout: config.Duration{Duration: time.Minute},
|
||||
})
|
||||
}
|
||||
|
||||
const parallelRouterName = "parallel-router"
|
||||
|
||||
routers[parallelRouterName] = config.RouterParser{
|
||||
Router: config.Router{
|
||||
Type: config.RouterTypeParallel,
|
||||
Parameters: &config.ComposableRouterParams{
|
||||
Routers: crs,
|
||||
},
|
||||
},
|
||||
}
|
||||
cfg := config.Config{
|
||||
Identity: testIdentity,
|
||||
Addresses: config.Addresses{
|
||||
Swarm: []string{"/ip4/0.0.0.0/tcp/0", "/ip4/0.0.0.0/udp/0/quic"},
|
||||
API: []string{"/ip4/127.0.0.1/tcp/0"},
|
||||
},
|
||||
Routing: config.Routing{
|
||||
Type: config.NewOptionalString("custom"),
|
||||
Routers: routers,
|
||||
Methods: config.Methods{
|
||||
config.MethodNameFindPeers: config.Method{
|
||||
RouterName: parallelRouterName,
|
||||
},
|
||||
config.MethodNameFindProviders: config.Method{
|
||||
RouterName: parallelRouterName,
|
||||
},
|
||||
config.MethodNameGetIPNS: config.Method{
|
||||
RouterName: parallelRouterName,
|
||||
},
|
||||
config.MethodNameProvide: config.Method{
|
||||
RouterName: parallelRouterName,
|
||||
},
|
||||
config.MethodNamePutIPNS: config.Method{
|
||||
RouterName: parallelRouterName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
r := &repo.Mock{
|
||||
C: cfg,
|
||||
D: syncds.MutexWrap(datastore.NewMapDatastore()),
|
||||
}
|
||||
|
||||
n, err := NewNode(context.Background(),
|
||||
&BuildCfg{
|
||||
Repo: r,
|
||||
Online: true,
|
||||
Routing: libp2p.ConstructDelegatedRouting(
|
||||
cfg.Routing.Routers,
|
||||
cfg.Routing.Methods,
|
||||
cfg.Identity.PeerID,
|
||||
cfg.Addresses,
|
||||
cfg.Identity.PrivKey,
|
||||
),
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func GeneratePeerID() (peer.ID, crypto.PrivKey, error) {
|
||||
priv, pk, err := crypto.GenerateEd25519Key(rand.Reader)
|
||||
if err != nil {
|
||||
return peer.ID(""), nil, err
|
||||
}
|
||||
|
||||
pid, err := peer.IDFromPublicKey(pk)
|
||||
return pid, priv, err
|
||||
}
|
||||
|
||||
type delegatedRoutingService struct {
|
||||
goodPeerID, badPeerID peer.ID
|
||||
pk1 crypto.PrivKey
|
||||
serviceID int
|
||||
}
|
||||
|
||||
func (drs *delegatedRoutingService) FindProviders(ctx context.Context, key cid.Cid) (<-chan client.FindProvidersAsyncResult, error) {
|
||||
return nil, errNotSupported
|
||||
}
|
||||
|
||||
func (drs *delegatedRoutingService) Provide(ctx context.Context, req *client.ProvideRequest) (<-chan client.ProvideAsyncResult, error) {
|
||||
return nil, errNotSupported
|
||||
}
|
||||
|
||||
func (drs *delegatedRoutingService) GetIPNS(ctx context.Context, id []byte) (<-chan client.GetIPNSAsyncResult, error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
ch := make(chan client.GetIPNSAsyncResult)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
defer cancel()
|
||||
|
||||
var out client.GetIPNSAsyncResult
|
||||
switch peer.ID(id) {
|
||||
case drs.goodPeerID:
|
||||
ie, err := ipns.Create(drs.pk1, []byte(fmt.Sprintf("RECORD FROM SERVICE %d", drs.serviceID)), 0, time.Now().Add(10*time.Hour), 100*time.Hour)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ieb, err := ie.Marshal()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
out = client.GetIPNSAsyncResult{
|
||||
Record: ieb,
|
||||
Err: nil,
|
||||
}
|
||||
case drs.badPeerID:
|
||||
out = client.GetIPNSAsyncResult{
|
||||
Record: nil,
|
||||
Err: errors.New("THE ERROR"),
|
||||
}
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case ch <- out:
|
||||
}
|
||||
}()
|
||||
|
||||
return ch, nil
|
||||
|
||||
}
|
||||
|
||||
func (drs *delegatedRoutingService) PutIPNS(ctx context.Context, id []byte, record []byte) (<-chan client.PutIPNSAsyncResult, error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
ch := make(chan client.PutIPNSAsyncResult)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
defer cancel()
|
||||
|
||||
var out client.PutIPNSAsyncResult
|
||||
switch peer.ID(id) {
|
||||
case drs.goodPeerID:
|
||||
out = client.PutIPNSAsyncResult{}
|
||||
case drs.badPeerID:
|
||||
out = client.PutIPNSAsyncResult{
|
||||
Err: fmt.Errorf("THE ERROR %d", drs.serviceID),
|
||||
}
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case ch <- out:
|
||||
}
|
||||
}()
|
||||
|
||||
return ch, nil
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/boxo/ipns"
|
||||
keystore "github.com/ipfs/boxo/keystore"
|
||||
"github.com/ipfs/boxo/namesys"
|
||||
"github.com/ipfs/kubo/tracing"
|
||||
@ -23,33 +24,18 @@ import (
|
||||
|
||||
type NameAPI CoreAPI
|
||||
|
||||
type ipnsEntry struct {
|
||||
name string
|
||||
value path.Path
|
||||
}
|
||||
|
||||
// Name returns the ipnsEntry name.
|
||||
func (e *ipnsEntry) Name() string {
|
||||
return e.name
|
||||
}
|
||||
|
||||
// Value returns the ipnsEntry value.
|
||||
func (e *ipnsEntry) Value() path.Path {
|
||||
return e.value
|
||||
}
|
||||
|
||||
// Publish announces new IPNS name and returns the new IPNS entry.
|
||||
func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.NamePublishOption) (coreiface.IpnsEntry, error) {
|
||||
func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.NamePublishOption) (ipns.Name, error) {
|
||||
ctx, span := tracing.Span(ctx, "CoreAPI.NameAPI", "Publish", trace.WithAttributes(attribute.String("path", p.String())))
|
||||
defer span.End()
|
||||
|
||||
if err := api.checkPublishAllowed(); err != nil {
|
||||
return nil, err
|
||||
return ipns.Name{}, err
|
||||
}
|
||||
|
||||
options, err := caopts.NamePublishOptions(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ipns.Name{}, err
|
||||
}
|
||||
span.SetAttributes(
|
||||
attribute.Bool("allowoffline", options.AllowOffline),
|
||||
@ -62,23 +48,24 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam
|
||||
|
||||
err = api.checkOnline(options.AllowOffline)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ipns.Name{}, err
|
||||
}
|
||||
|
||||
pth, err := ipath.ParsePath(p.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ipns.Name{}, err
|
||||
}
|
||||
|
||||
k, err := keylookup(api.privateKey, api.repo.Keystore(), options.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ipns.Name{}, err
|
||||
}
|
||||
|
||||
eol := time.Now().Add(options.ValidTime)
|
||||
|
||||
publishOptions := []nsopts.PublishOption{
|
||||
nsopts.PublishWithEOL(eol),
|
||||
nsopts.PublishCompatibleWithV1(options.CompatibleWithV1),
|
||||
}
|
||||
|
||||
if options.TTL != nil {
|
||||
@ -87,18 +74,15 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam
|
||||
|
||||
err = api.namesys.Publish(ctx, k, pth, publishOptions...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ipns.Name{}, err
|
||||
}
|
||||
|
||||
pid, err := peer.IDFromPrivateKey(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ipns.Name{}, err
|
||||
}
|
||||
|
||||
return &ipnsEntry{
|
||||
name: coreiface.FormatKeyID(pid),
|
||||
value: p,
|
||||
}, nil
|
||||
return ipns.NameFromPeer(pid), nil
|
||||
}
|
||||
|
||||
func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.NameResolveOption) (<-chan coreiface.IpnsResult, error) {
|
||||
|
||||
@ -84,7 +84,7 @@ This section covers tasks to be done ahead of the release.
|
||||
|
||||
This section covers tasks to be done during each release.
|
||||
|
||||
- [ ] Prepare the release branch and update version numbers accordingly <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) prepare-branch` or ...</summary>
|
||||
- [ ] Prepare the release branch and update version numbers accordingly <details><summary>using `./kuboreleaser --skip-check-before release --version vX.Y.Z(-rcN) prepare-branch` or ...</summary>
|
||||
- [ ] create a new branch `release-vX.Y.Z`
|
||||
- use `master` as base if `Z == 0`
|
||||
- use `release` as base if `Z > 0`
|
||||
@ -105,7 +105,7 @@ This section covers tasks to be done during each release.
|
||||
</details>
|
||||
- [ ] Run Thunderdome testing, see the [Thunderdome release docs](./releases_thunderdome.md) for details
|
||||
- [ ] create a PR and merge the experiment config into Thunderdome
|
||||
- [ ] Create the release tag <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) tag` or ...</summary>
|
||||
- [ ] Create the release tag <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) tag` or ...</summary>
|
||||
- This is a dangerous operation! Go and Docker publishing are difficult to reverse! Have the release reviewer verify all the commands marked with ⚠️!
|
||||
- [ ] ⚠️  tag the HEAD commit using `git tag -s vX.Y.Z(-RCN) -m 'Prerelease X.Y.Z(-RCN)'`
|
||||
- [ ] ⚠️  tag the HEAD commit of the `release` branch using `git tag -s vX.Y.Z(-RCN) -m 'Release X.Y.Z(-RCN)'`
|
||||
@ -113,10 +113,10 @@ This section covers tasks to be done during each release.
|
||||
- [ ] ⚠️ push the tag to GitHub using `git push origin vX.Y.Z(-RCN)`
|
||||
- do **NOT** use `git push --tags` because it pushes all your local tags
|
||||
</details>
|
||||
- [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/) <details><summary>using `kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-dockerhub` or ...</summary>
|
||||
- [ ] Publish the release to [DockerHub](https://hub.docker.com/r/ipfs/kubo/) <details><summary>using `./kuboreleaser --skip-check-before --skip-run release --version vX.Y.Z(-rcN) publish-to-dockerhub` or ...</summary>
|
||||
- [ ] Wait for [Publish docker image](https://github.com/ipfs/kubo/actions/workflows/docker-image.yml) workflow run initiated by the tag push to finish
|
||||
- [ ] verify the image is available on [Docker Hub](https://hub.docker.com/r/ipfs/kubo/tags)
|
||||
- [ ] Publish the release to [ipfs.tech](https://dist.ipfs.tech) <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ...</summary>
|
||||
- [ ] Publish the release to [ipfs.tech](https://dist.ipfs.tech) <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-distributions` or ...</summary>
|
||||
- [ ] check out [ipfs/distributions](https://github.com/ipfs/distributions)
|
||||
- [ ] run `./dist.sh add-version kubo vX.Y.Z(-RCN)` to add the new version to the `versions` file
|
||||
- [usage](https://github.com/ipfs/distributions#usage)
|
||||
@ -125,12 +125,12 @@ This section covers tasks to be done during each release.
|
||||
- [ ] wait for the [CI](https://github.com/ipfs/distributions/actions/workflows/main.yml) workflow run initiated by the merge to master to finish
|
||||
- [ ] verify the release is available on [dist.ipfs.io](https://dist.ipfs.io/#kubo)
|
||||
</details>
|
||||
- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` or ...</summary>
|
||||
- [ ] Publish the release to [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions) <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-npm` (⚠️ you might need to run the command a couple of times because GHA might not be able to see the new distribution straight away due to caching) or ...</summary>
|
||||
- [ ] run the [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow
|
||||
- [ ] check [Release to npm](https://github.com/ipfs/npm-go-ipfs/actions/workflows/main.yml) workflow run logs to verify it discovered the new release
|
||||
- [ ] verify the release is available on [NPM](https://www.npmjs.com/package/go-ipfs?activeTab=versions)
|
||||
</details>
|
||||
- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases) <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) publish-to-github` or ...</summary>
|
||||
- [ ] Publish the release to [GitHub](https://github.com/ipfs/kubo/releases) <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) publish-to-github` or ...</summary>
|
||||
- [ ] create a new release on [GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release)
|
||||
- [RC example](https://github.com/ipfs/kubo/releases/tag/v0.17.0-rc1)
|
||||
- [FINAL example](https://github.com/ipfs/kubo/releases/tag/v0.17.0)
|
||||
@ -144,7 +144,7 @@ This section covers tasks to be done during each release.
|
||||
- [ ] wait for the [sync-release-assets](https://github.com/ipfs/kubo/actions/workflows/sync-release-assets.yml) workflow run to finish
|
||||
- [ ] verify the release assets are present in the [GitHub release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN))
|
||||
</details>
|
||||
- [ ] Promote the release <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) promote` or ...</summary>
|
||||
- [ ] Promote the release <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) promote` or ...</summary>
|
||||
- [ ] create an [IPFS Discourse](https://discuss.ipfs.tech) topic
|
||||
- [prerelease example](https://discuss.ipfs.tech/t/kubo-v0-16-0-rc1-release-candidate-is-out/15248)
|
||||
- [release example](https://discuss.ipfs.tech/t/kubo-v0-16-0-release-is-out/15249)
|
||||
@ -169,38 +169,38 @@ This section covers tasks to be done during each release.
|
||||
- [ ]   post the link to the [GitHub Release](https://github.com/ipfs/kubo/releases/tag/vX.Y.Z(-RCN)) to [Reddit](https://reddit.com/r/ipfs)
|
||||
- [example](https://www.reddit.com/r/ipfs/comments/9x0q0k/kubo_v0160_release_is_out/)
|
||||
</details>
|
||||
- [ ] Test the new version with `ipfs-companion` <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) test-ipfs-companion` or ...</summary>
|
||||
- [ ] Test the new version with `ipfs-companion` <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) test-ipfs-companion` or ...</summary>
|
||||
- [ ] run the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml)
|
||||
- use `vX.Y.Z(-RCN)` as the Kubo image version
|
||||
- [ ] wait for the [e2e](https://github.com/ipfs/ipfs-companion/actions/workflows/e2e.yml) workflow run to finish
|
||||
</details>
|
||||
- [ ]  Update Kubo in [interop](https://github.com/ipfs/interop) <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) update-interop` or ...</summary>
|
||||
- [ ]  Update Kubo in [interop](https://github.com/ipfs/interop) <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) update-interop` or ...</summary>
|
||||
- [ ]  check out [ipfs/interop](https://github.com/ipfs/interop)
|
||||
- [ ]  run `npm install`
|
||||
- [ ]  create a PR which updates `package.json` and `package-lock.json`
|
||||
- [ ]  merge the PR
|
||||
</details>
|
||||
- [ ]  Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop) <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-desktop` or ...</summary>
|
||||
- [ ]  Update Kubo in [ipfs-desktop](https://github.com/ipfs/ipfs-desktop) <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-desktop` or ...</summary>
|
||||
- [ ] check out [ipfs/ipfs-desktop](https://github.com/ipfs/ipfs-desktop)
|
||||
- [ ] run `npm install`
|
||||
- [ ] create a PR which updates `package.json` and `package-lock.json`
|
||||
- [ ]  add @SgtPooki and @whizzzkid as reviewers
|
||||
</details>
|
||||
- [ ]  Update Kubo docs <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-docs` or ...</summary>
|
||||
- [ ]  Update Kubo docs <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-docs` or ...</summary>
|
||||
- [ ]  run the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow
|
||||
- [ ]  merge the PR created by the [update-on-new-ipfs-tag.yml](https://github.com/ipfs/ipfs-docs/actions/workflows/update-on-new-ipfs-tag.yml) workflow run
|
||||
</details>
|
||||
- [ ]  Create a blog entry on [ipfs.tech](https://blog.ipfs.tech) <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-blog --date YYYY-MM-DD` or ...</summary>
|
||||
- [ ]  Create a blog entry on [ipfs.tech](https://blog.ipfs.tech) <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) update-ipfs-blog --date YYYY-MM-DD` or ...</summary>
|
||||
- [ ]  create a PR which adds a release note for the new Kubo version
|
||||
- [example](https://github.com/ipfs/ipfs-blog/pull/529)
|
||||
- [ ]  merge the PR
|
||||
- [ ]  verify the blog entry was published
|
||||
</details>
|
||||
- [ ]  Merge the [release](https://github.com/ipfs/kubo/tree/release) branch back into [master](https://github.com/ipfs/kubo/tree/master), ignoring the changes to [version.go](version.go) (keep the `-dev`) version, <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) merge-branch` or ...</summary>
|
||||
- [ ]  Merge the [release](https://github.com/ipfs/kubo/tree/release) branch back into [master](https://github.com/ipfs/kubo/tree/master), ignoring the changes to [version.go](version.go) (keep the `-dev`) version, <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) merge-branch` or ...</summary>
|
||||
- [ ] create a new branch `merge-release-vX.Y.Z` from `release`
|
||||
- [ ] create and merge a PR from `merge-release-vX.Y.Z` to `master`
|
||||
</details>
|
||||
- [ ]   Prepare for the next release <details><summary>using `kuboreleaser release --version vX.Y.Z(-rcN) prepare-next` or ...</summary>
|
||||
- [ ]   Prepare for the next release <details><summary>using `./kuboreleaser release --version vX.Y.Z(-rcN) prepare-next` or ...</summary>
|
||||
- [ ]   Create the next [changelog](https://github.com/ipfs/kubo/blob/master/docs/changelogs/vX.(Y+1).md)
|
||||
- [ ]   Link to the new changelog in the [CHANGELOG.md](CHANGELOG.md) file
|
||||
- [ ]   Create the next release issue
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
- [Overview](#overview)
|
||||
- [🔦 Highlights](#-highlights)
|
||||
- [`ipfs name publish` now supports V2 only IPNS records](#ipfs-name-publish-now-supports-v2-only-ipns-records)
|
||||
- [📝 Changelog](#-changelog)
|
||||
- [👨👩👧👦 Contributors](#-contributors)
|
||||
|
||||
@ -13,6 +14,15 @@
|
||||
|
||||
### 🔦 Highlights
|
||||
|
||||
#### `ipfs name publish` now supports V2 only IPNS records
|
||||
|
||||
When publishing an IPNS record, you are now able to create v2 only records
|
||||
by passing `--v1compat=false`. By default, we still create V1+V2 records, such
|
||||
that there is the highest chance of backwards compatibility. The goal is to move
|
||||
to V2 only in the future.
|
||||
|
||||
**TODO**: add links to IPIP https://github.com/ipfs/specs/issues/376
|
||||
|
||||
### 📝 Changelog
|
||||
|
||||
### 👨👩👧👦 Contributors
|
||||
|
||||
@ -663,20 +663,7 @@ Type: `flag`
|
||||
|
||||
Headers to set on gateway responses.
|
||||
|
||||
Default:
|
||||
```json
|
||||
{
|
||||
"Access-Control-Allow-Headers": [
|
||||
"X-Requested-With"
|
||||
],
|
||||
"Access-Control-Allow-Methods": [
|
||||
"GET"
|
||||
],
|
||||
"Access-Control-Allow-Origin": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
```
|
||||
Default: `{}` + implicit CORS headers from `boxo/gateway#AddAccessControlHeaders` and [ipfs/specs#423](https://github.com/ipfs/specs/issues/423)
|
||||
|
||||
Type: `object[string -> array[string]]`
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ go 1.18
|
||||
replace github.com/ipfs/kubo => ./../../..
|
||||
|
||||
require (
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191
|
||||
github.com/ipfs/kubo v0.0.0-00010101000000-000000000000
|
||||
github.com/libp2p/go-libp2p v0.27.7
|
||||
github.com/multiformats/go-multiaddr v0.9.0
|
||||
@ -65,7 +65,6 @@ require (
|
||||
github.com/ipfs/go-cid v0.4.1 // indirect
|
||||
github.com/ipfs/go-cidutil v0.1.0 // indirect
|
||||
github.com/ipfs/go-datastore v0.6.0 // indirect
|
||||
github.com/ipfs/go-delegated-routing v0.8.0 // indirect
|
||||
github.com/ipfs/go-ds-badger v0.3.0 // indirect
|
||||
github.com/ipfs/go-ds-flatfs v0.5.1 // indirect
|
||||
github.com/ipfs/go-ds-leveldb v0.5.0 // indirect
|
||||
@ -88,7 +87,7 @@ require (
|
||||
github.com/ipfs/go-metrics-interface v0.0.1 // indirect
|
||||
github.com/ipfs/go-peertaskqueue v0.8.1 // indirect
|
||||
github.com/ipfs/go-unixfsnode v1.7.1 // indirect
|
||||
github.com/ipld/edelweiss v0.2.0 // indirect
|
||||
github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 // indirect
|
||||
github.com/ipld/go-codec-dagpb v1.6.0 // indirect
|
||||
github.com/ipld/go-ipld-prime v0.20.0 // indirect
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||
|
||||
@ -320,8 +320,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
||||
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 h1:SGbw381zt6c1VFf3QCBaJ+eVJ4AwD9fPaFKFp9U9Apk=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 h1:oNiEZXJYb4B6zmvUc3F5vvS4xtll8naN8rz1hKftgd4=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w=
|
||||
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
|
||||
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
|
||||
github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=
|
||||
@ -344,8 +344,6 @@ github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRV
|
||||
github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk=
|
||||
github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk=
|
||||
github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8=
|
||||
github.com/ipfs/go-delegated-routing v0.8.0 h1:faiRi4k8YioTxU2x7+pnrLQjR7jIQhGWN2JvCwcQ/aU=
|
||||
github.com/ipfs/go-delegated-routing v0.8.0/go.mod h1:18Dds6ZoNTsff9S/7R49Nh2t2YNXIIKR/RLQmBZdjjY=
|
||||
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
|
||||
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
||||
github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk=
|
||||
@ -404,7 +402,7 @@ github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Ax
|
||||
github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g=
|
||||
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
|
||||
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
|
||||
github.com/ipfs/go-merkledag v0.10.0 h1:IUQhj/kzTZfam4e+LnaEpoiZ9vZF6ldimVlby+6OXL4=
|
||||
github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY=
|
||||
github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg=
|
||||
github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY=
|
||||
github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg=
|
||||
@ -413,9 +411,8 @@ github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU=
|
||||
github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s=
|
||||
github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk=
|
||||
github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs=
|
||||
github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk=
|
||||
github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4=
|
||||
github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g=
|
||||
github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s=
|
||||
github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33/go.mod h1:sQEkXVM3csejlb1kCCb+vQ/pWBKX9QtvsrysMQjOgOg=
|
||||
github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc=
|
||||
github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s=
|
||||
github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8=
|
||||
|
||||
16
go.mod
16
go.mod
@ -13,15 +13,13 @@ require (
|
||||
github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302
|
||||
github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191
|
||||
github.com/ipfs/go-block-format v0.1.2
|
||||
github.com/ipfs/go-cid v0.4.1
|
||||
github.com/ipfs/go-cidutil v0.1.0
|
||||
github.com/ipfs/go-datastore v0.6.0
|
||||
github.com/ipfs/go-delegated-routing v0.8.0
|
||||
github.com/ipfs/go-detect-race v0.0.1
|
||||
github.com/ipfs/go-ds-badger v0.3.0
|
||||
github.com/ipfs/go-ds-flatfs v0.5.1
|
||||
@ -38,6 +36,8 @@ require (
|
||||
github.com/ipfs/go-metrics-interface v0.0.1
|
||||
github.com/ipfs/go-metrics-prometheus v0.0.2
|
||||
github.com/ipfs/go-unixfsnode v1.7.1
|
||||
github.com/ipld/go-car v0.5.0
|
||||
github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33
|
||||
github.com/ipld/go-codec-dagpb v1.6.0
|
||||
github.com/ipld/go-ipld-prime v0.20.0
|
||||
github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c
|
||||
@ -86,6 +86,7 @@ require (
|
||||
golang.org/x/mod v0.10.0
|
||||
golang.org/x/sync v0.2.0
|
||||
golang.org/x/sys v0.9.0
|
||||
google.golang.org/protobuf v1.30.0
|
||||
)
|
||||
|
||||
require (
|
||||
@ -116,6 +117,7 @@ require (
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
@ -131,16 +133,19 @@ require (
|
||||
github.com/huin/goupnp v1.2.0 // indirect
|
||||
github.com/ipfs/bbloom v0.0.4 // indirect
|
||||
github.com/ipfs/go-bitfield v1.1.0 // indirect
|
||||
github.com/ipfs/go-blockservice v0.5.0 // indirect
|
||||
github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect
|
||||
github.com/ipfs/go-ipfs-delay v0.0.1 // indirect
|
||||
github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect
|
||||
github.com/ipfs/go-ipfs-exchange-interface v0.2.0 // indirect
|
||||
github.com/ipfs/go-ipfs-pq v0.0.3 // indirect
|
||||
github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect
|
||||
github.com/ipfs/go-ipfs-util v0.0.3 // indirect
|
||||
github.com/ipfs/go-ipld-cbor v0.0.6 // indirect
|
||||
github.com/ipfs/go-libipfs v0.7.0 // indirect
|
||||
github.com/ipfs/go-merkledag v0.11.0 // indirect
|
||||
github.com/ipfs/go-peertaskqueue v0.8.1 // indirect
|
||||
github.com/ipld/edelweiss v0.2.0 // indirect
|
||||
github.com/ipfs/go-verifcid v0.0.2 // indirect
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
@ -227,7 +232,6 @@ require (
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
||||
google.golang.org/grpc v1.55.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
@ -235,4 +239,4 @@ require (
|
||||
nhooyr.io/websocket v1.8.7 // indirect
|
||||
)
|
||||
|
||||
go 1.18
|
||||
go 1.19
|
||||
|
||||
20
go.sum
20
go.sum
@ -355,15 +355,17 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
||||
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 h1:SGbw381zt6c1VFf3QCBaJ+eVJ4AwD9fPaFKFp9U9Apk=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 h1:oNiEZXJYb4B6zmvUc3F5vvS4xtll8naN8rz1hKftgd4=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w=
|
||||
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
|
||||
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
|
||||
github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ=
|
||||
github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=
|
||||
github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk=
|
||||
github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo=
|
||||
github.com/ipfs/go-block-format v0.1.2/go.mod h1:mACVcrxarQKstUU3Yf/RdwbC4DzPV6++rO2a3d+a/KE=
|
||||
github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4bYLEY=
|
||||
github.com/ipfs/go-blockservice v0.5.0/go.mod h1:W6brZ5k20AehbmERplmERn8o2Ni3ZZubvAxaIUeaT6w=
|
||||
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||
github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||
github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M=
|
||||
@ -379,8 +381,6 @@ github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRV
|
||||
github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk=
|
||||
github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk=
|
||||
github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8=
|
||||
github.com/ipfs/go-delegated-routing v0.8.0 h1:faiRi4k8YioTxU2x7+pnrLQjR7jIQhGWN2JvCwcQ/aU=
|
||||
github.com/ipfs/go-delegated-routing v0.8.0/go.mod h1:18Dds6ZoNTsff9S/7R49Nh2t2YNXIIKR/RLQmBZdjjY=
|
||||
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
|
||||
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
||||
github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk=
|
||||
@ -409,6 +409,7 @@ github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG
|
||||
github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q=
|
||||
github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU=
|
||||
github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y=
|
||||
github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y=
|
||||
github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA=
|
||||
github.com/ipfs/go-ipfs-files v0.3.0 h1:fallckyc5PYjuMEitPNrjRfpwl7YFt69heCOUhsbGxQ=
|
||||
github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs=
|
||||
@ -416,6 +417,7 @@ github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE
|
||||
github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4=
|
||||
github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8=
|
||||
github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk=
|
||||
github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc=
|
||||
github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc=
|
||||
github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ=
|
||||
github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0=
|
||||
@ -441,7 +443,8 @@ github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Ax
|
||||
github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g=
|
||||
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
|
||||
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
|
||||
github.com/ipfs/go-merkledag v0.10.0 h1:IUQhj/kzTZfam4e+LnaEpoiZ9vZF6ldimVlby+6OXL4=
|
||||
github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY=
|
||||
github.com/ipfs/go-merkledag v0.11.0/go.mod h1:Q4f/1ezvBiJV0YCIXvt51W/9/kqJGH4I1LsA7+djsM4=
|
||||
github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg=
|
||||
github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY=
|
||||
github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZaGVF1CUVdE+s=
|
||||
@ -452,10 +455,11 @@ github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU=
|
||||
github.com/ipfs/go-unixfsnode v1.7.1 h1:RRxO2b6CSr5UQ/kxnGzaChTjp5LWTdf3Y4n8ANZgB/s=
|
||||
github.com/ipfs/go-unixfsnode v1.7.1/go.mod h1:PVfoyZkX1B34qzT3vJO4nsLUpRCyhnMuHBznRcXirlk=
|
||||
github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs=
|
||||
github.com/ipld/edelweiss v0.2.0 h1:KfAZBP8eeJtrLxLhi7r3N0cBCo7JmwSRhOJp3WSpNjk=
|
||||
github.com/ipld/edelweiss v0.2.0/go.mod h1:FJAzJRCep4iI8FOFlRriN9n0b7OuX3T/S9++NpBDmA4=
|
||||
github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU=
|
||||
github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8=
|
||||
github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g=
|
||||
github.com/ipld/go-car v0.5.0/go.mod h1:ppiN5GWpjOZU9PgpAZ9HbZd9ZgSpwPMr48fGRJOWmvE=
|
||||
github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s=
|
||||
github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33/go.mod h1:sQEkXVM3csejlb1kCCb+vQ/pWBKX9QtvsrysMQjOgOg=
|
||||
github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc=
|
||||
github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s=
|
||||
github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8=
|
||||
|
||||
@ -10,8 +10,6 @@ import (
|
||||
drclient "github.com/ipfs/boxo/routing/http/client"
|
||||
"github.com/ipfs/boxo/routing/http/contentrouter"
|
||||
"github.com/ipfs/go-datastore"
|
||||
drc "github.com/ipfs/go-delegated-routing/client"
|
||||
drp "github.com/ipfs/go-delegated-routing/gen/proto"
|
||||
logging "github.com/ipfs/go-log"
|
||||
version "github.com/ipfs/kubo"
|
||||
"github.com/ipfs/kubo/config"
|
||||
@ -25,7 +23,6 @@ import (
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/routing"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
"github.com/multiformats/go-multicodec"
|
||||
"go.opencensus.io/stats/view"
|
||||
)
|
||||
|
||||
@ -96,8 +93,6 @@ func parse(visited map[string]bool,
|
||||
switch cfg.Type {
|
||||
case config.RouterTypeHTTP:
|
||||
router, err = httpRoutingFromConfig(cfg.Router, extraHTTP)
|
||||
case config.RouterTypeReframe:
|
||||
router, err = reframeRoutingFromConfig(cfg.Router, extraHTTP)
|
||||
case config.RouterTypeDHT:
|
||||
router, err = dhtRoutingFromConfig(cfg.Router, extraDHT)
|
||||
case config.RouterTypeParallel:
|
||||
@ -232,67 +227,6 @@ func httpRoutingFromConfig(conf config.Router, extraHTTP *ExtraHTTPParams) (rout
|
||||
}, nil
|
||||
}
|
||||
|
||||
func reframeRoutingFromConfig(conf config.Router, extraReframe *ExtraHTTPParams) (routing.Routing, error) {
|
||||
var dr drp.DelegatedRouting_Client
|
||||
|
||||
params := conf.Parameters.(*config.ReframeRouterParams)
|
||||
|
||||
if params.Endpoint == "" {
|
||||
return nil, NewParamNeededErr("Endpoint", conf.Type)
|
||||
}
|
||||
|
||||
// Increase per-host connection pool since we are making lots of concurrent requests.
|
||||
transport := http.DefaultTransport.(*http.Transport).Clone()
|
||||
transport.MaxIdleConns = 500
|
||||
transport.MaxIdleConnsPerHost = 100
|
||||
|
||||
delegateHTTPClient := &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
dr, err := drp.New_DelegatedRouting_Client(params.Endpoint,
|
||||
drp.DelegatedRouting_Client_WithHTTPClient(delegateHTTPClient),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var c *drc.Client
|
||||
|
||||
err = view.Register(drc.DefaultViews...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("registering delegated routing views: %w", err)
|
||||
}
|
||||
|
||||
// this path is for tests only
|
||||
if extraReframe == nil {
|
||||
c, err = drc.NewClient(dr, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
prov, err := createProvider(extraReframe.PeerID, extraReframe.Addrs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key, err := decodePrivKey(extraReframe.PrivKeyB64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err = drc.NewClient(dr, prov, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
crc := drc.NewContentRoutingClient(c)
|
||||
return &reframeRoutingWrapper{
|
||||
Client: c,
|
||||
ContentRoutingClient: crc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodePrivKey(keyB64 string) (ic.PrivKey, error) {
|
||||
pk, err := base64.StdEncoding.DecodeString(keyB64)
|
||||
if err != nil {
|
||||
@ -324,19 +258,6 @@ func createAddrInfo(peerID string, addrs []string) (peer.AddrInfo, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func createProvider(peerID string, addrs []string) (*drc.Provider, error) {
|
||||
addrInfo, err := createAddrInfo(peerID, addrs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &drc.Provider{
|
||||
Peer: addrInfo,
|
||||
ProviderProto: []drc.TransferProtocol{
|
||||
{Codec: multicodec.TransportBitswap},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
type ExtraDHTParams struct {
|
||||
BootstrapPeers []peer.AddrInfo
|
||||
Host host.Host
|
||||
|
||||
@ -1,68 +1,27 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"testing"
|
||||
|
||||
"github.com/ipfs/kubo/config"
|
||||
crypto "github.com/libp2p/go-libp2p/core/crypto"
|
||||
peer "github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestReframeRoutingFromConfig(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
r, err := reframeRoutingFromConfig(config.Router{
|
||||
Type: config.RouterTypeReframe,
|
||||
Parameters: &config.ReframeRouterParams{},
|
||||
}, nil)
|
||||
|
||||
require.Nil(r)
|
||||
require.EqualError(err, "configuration param 'Endpoint' is needed for reframe delegated routing types")
|
||||
|
||||
r, err = reframeRoutingFromConfig(config.Router{
|
||||
Type: config.RouterTypeReframe,
|
||||
Parameters: &config.ReframeRouterParams{
|
||||
Endpoint: "test",
|
||||
},
|
||||
}, nil)
|
||||
|
||||
require.NoError(err)
|
||||
require.NotNil(r)
|
||||
|
||||
priv, pub, err := crypto.GenerateKeyPair(crypto.RSA, 2048)
|
||||
require.NoError(err)
|
||||
|
||||
id, err := peer.IDFromPublicKey(pub)
|
||||
require.NoError(err)
|
||||
|
||||
privM, err := crypto.MarshalPrivateKey(priv)
|
||||
require.NoError(err)
|
||||
|
||||
r, err = reframeRoutingFromConfig(config.Router{
|
||||
Type: config.RouterTypeReframe,
|
||||
Parameters: &config.ReframeRouterParams{
|
||||
Endpoint: "test",
|
||||
},
|
||||
}, &ExtraHTTPParams{
|
||||
PeerID: id.String(),
|
||||
Addrs: []string{"/ip4/0.0.0.0/tcp/4001"},
|
||||
PrivKeyB64: base64.StdEncoding.EncodeToString(privM),
|
||||
})
|
||||
|
||||
require.NotNil(r)
|
||||
require.NoError(err)
|
||||
}
|
||||
|
||||
func TestParser(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
pid, sk, err := generatePeerID()
|
||||
require.NoError(err)
|
||||
|
||||
router, err := Parse(config.Routers{
|
||||
"r1": config.RouterParser{
|
||||
Router: config.Router{
|
||||
Type: config.RouterTypeReframe,
|
||||
Parameters: &config.ReframeRouterParams{
|
||||
Type: config.RouterTypeHTTP,
|
||||
Parameters: &config.HTTPRouterParams{
|
||||
Endpoint: "testEndpoint",
|
||||
},
|
||||
},
|
||||
@ -95,7 +54,10 @@ func TestParser(t *testing.T) {
|
||||
config.MethodNameProvide: config.Method{
|
||||
RouterName: "r2",
|
||||
},
|
||||
}, &ExtraDHTParams{}, nil)
|
||||
}, &ExtraDHTParams{}, &ExtraHTTPParams{
|
||||
PeerID: string(pid),
|
||||
PrivKeyB64: sk,
|
||||
})
|
||||
|
||||
require.NoError(err)
|
||||
|
||||
@ -109,27 +71,30 @@ func TestParser(t *testing.T) {
|
||||
func TestParserRecursive(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
pid, sk, err := generatePeerID()
|
||||
require.NoError(err)
|
||||
|
||||
router, err := Parse(config.Routers{
|
||||
"reframe1": config.RouterParser{
|
||||
"http1": config.RouterParser{
|
||||
Router: config.Router{
|
||||
Type: config.RouterTypeReframe,
|
||||
Parameters: &config.ReframeRouterParams{
|
||||
Type: config.RouterTypeHTTP,
|
||||
Parameters: &config.HTTPRouterParams{
|
||||
Endpoint: "testEndpoint1",
|
||||
},
|
||||
},
|
||||
},
|
||||
"reframe2": config.RouterParser{
|
||||
"http2": config.RouterParser{
|
||||
Router: config.Router{
|
||||
Type: config.RouterTypeReframe,
|
||||
Parameters: &config.ReframeRouterParams{
|
||||
Type: config.RouterTypeHTTP,
|
||||
Parameters: &config.HTTPRouterParams{
|
||||
Endpoint: "testEndpoint2",
|
||||
},
|
||||
},
|
||||
},
|
||||
"reframe3": config.RouterParser{
|
||||
"http3": config.RouterParser{
|
||||
Router: config.Router{
|
||||
Type: config.RouterTypeReframe,
|
||||
Parameters: &config.ReframeRouterParams{
|
||||
Type: config.RouterTypeHTTP,
|
||||
Parameters: &config.HTTPRouterParams{
|
||||
Endpoint: "testEndpoint3",
|
||||
},
|
||||
},
|
||||
@ -140,10 +105,10 @@ func TestParserRecursive(t *testing.T) {
|
||||
Parameters: &config.ComposableRouterParams{
|
||||
Routers: []config.ConfigRouter{
|
||||
{
|
||||
RouterName: "reframe1",
|
||||
RouterName: "http1",
|
||||
},
|
||||
{
|
||||
RouterName: "reframe2",
|
||||
RouterName: "http2",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -158,7 +123,7 @@ func TestParserRecursive(t *testing.T) {
|
||||
RouterName: "composable1",
|
||||
},
|
||||
{
|
||||
RouterName: "reframe3",
|
||||
RouterName: "http3",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -180,7 +145,10 @@ func TestParserRecursive(t *testing.T) {
|
||||
config.MethodNameProvide: config.Method{
|
||||
RouterName: "composable2",
|
||||
},
|
||||
}, &ExtraDHTParams{}, nil)
|
||||
}, &ExtraDHTParams{}, &ExtraHTTPParams{
|
||||
PeerID: string(pid),
|
||||
PrivKeyB64: sk,
|
||||
})
|
||||
|
||||
require.NoError(err)
|
||||
|
||||
@ -237,3 +205,23 @@ func TestParserRecursiveLoop(t *testing.T) {
|
||||
|
||||
require.ErrorContains(err, "dependency loop creating router with name \"composable2\"")
|
||||
}
|
||||
|
||||
func generatePeerID() (string, string, error) {
|
||||
sk, pk, err := crypto.GenerateEd25519Key(rand.Reader)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
bytes, err := crypto.MarshalPrivateKey(sk)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
enc := base64.StdEncoding.EncodeToString(bytes)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
pid, err := peer.IDFromPublicKey(pk)
|
||||
return pid.String(), enc, err
|
||||
}
|
||||
|
||||
@ -3,39 +3,11 @@ package routing
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
drc "github.com/ipfs/go-delegated-routing/client"
|
||||
routinghelpers "github.com/libp2p/go-libp2p-routing-helpers"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/routing"
|
||||
)
|
||||
|
||||
var _ routing.Routing = &reframeRoutingWrapper{}
|
||||
var _ routinghelpers.ProvideManyRouter = &reframeRoutingWrapper{}
|
||||
|
||||
// reframeRoutingWrapper is a wrapper needed to construct the routing.Routing interface from
|
||||
// delegated-routing library.
|
||||
type reframeRoutingWrapper struct {
|
||||
*drc.Client
|
||||
*drc.ContentRoutingClient
|
||||
}
|
||||
|
||||
func (c *reframeRoutingWrapper) Provide(ctx context.Context, id cid.Cid, announce bool) error {
|
||||
return c.ContentRoutingClient.Provide(ctx, id, announce)
|
||||
}
|
||||
|
||||
func (c *reframeRoutingWrapper) FindProvidersAsync(ctx context.Context, cid cid.Cid, count int) <-chan peer.AddrInfo {
|
||||
return c.ContentRoutingClient.FindProvidersAsync(ctx, cid, count)
|
||||
}
|
||||
|
||||
func (c *reframeRoutingWrapper) Bootstrap(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *reframeRoutingWrapper) FindPeer(ctx context.Context, id peer.ID) (peer.AddrInfo, error) {
|
||||
return peer.AddrInfo{}, routing.ErrNotSupported
|
||||
}
|
||||
|
||||
type ProvideManyRouter interface {
|
||||
routinghelpers.ProvideManyRouter
|
||||
routing.Routing
|
||||
|
||||
BIN
test/cli/fixtures/TestName.car
Normal file
BIN
test/cli/fixtures/TestName.car
Normal file
Binary file not shown.
266
test/cli/name_test.go
Normal file
266
test/cli/name_test.go
Normal file
@ -0,0 +1,266 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/ipfs/boxo/ipns"
|
||||
"github.com/ipfs/kubo/core/commands/name"
|
||||
"github.com/ipfs/kubo/test/cli/harness"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestName(t *testing.T) {
|
||||
const (
|
||||
fixturePath = "fixtures/TestName.car"
|
||||
fixtureCid = "bafybeidg3uxibfrt7uqh7zd5yaodetik7wjwi4u7rwv2ndbgj6ec7lsv2a"
|
||||
dagCid = "bafyreidgts62p4rtg3rtmptmbv2dt46zjzin275fr763oku3wfod3quzay"
|
||||
)
|
||||
|
||||
makeDaemon := func(t *testing.T, initArgs []string) *harness.Node {
|
||||
node := harness.NewT(t).NewNode().Init(append([]string{"--profile=test"}, initArgs...)...)
|
||||
r, err := os.Open(fixturePath)
|
||||
require.Nil(t, err)
|
||||
defer r.Close()
|
||||
err = node.IPFSDagImport(r, fixtureCid)
|
||||
require.NoError(t, err)
|
||||
return node
|
||||
}
|
||||
|
||||
testPublishingWithSelf := func(keyType string) {
|
||||
t.Run("Publishing with self (keyType = "+keyType+")", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
args := []string{}
|
||||
if keyType != "default" {
|
||||
args = append(args, "-a="+keyType)
|
||||
}
|
||||
|
||||
node := makeDaemon(t, args)
|
||||
name := ipns.NameFromPeer(node.PeerID())
|
||||
|
||||
t.Run("Publishing a CID", func(t *testing.T) {
|
||||
publishPath := "/ipfs/" + fixtureCid
|
||||
|
||||
res := node.IPFS("name", "publish", "--allow-offline", publishPath)
|
||||
require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name.String(), publishPath), res.Stdout.String())
|
||||
|
||||
res = node.IPFS("name", "resolve", "/ipns/"+name.String())
|
||||
require.Equal(t, publishPath+"\n", res.Stdout.String())
|
||||
})
|
||||
|
||||
t.Run("Publishing a CID with -Q option", func(t *testing.T) {
|
||||
publishPath := "/ipfs/" + fixtureCid
|
||||
|
||||
res := node.IPFS("name", "publish", "--allow-offline", "-Q", publishPath)
|
||||
require.Equal(t, name.String()+"\n", res.Stdout.String())
|
||||
|
||||
res = node.IPFS("name", "resolve", "/ipns/"+name.String())
|
||||
require.Equal(t, publishPath+"\n", res.Stdout.String())
|
||||
})
|
||||
|
||||
t.Run("Publishing a CID+subpath", func(t *testing.T) {
|
||||
publishPath := "/ipfs/" + fixtureCid + "/hello"
|
||||
|
||||
res := node.IPFS("name", "publish", "--allow-offline", publishPath)
|
||||
require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name.String(), publishPath), res.Stdout.String())
|
||||
|
||||
res = node.IPFS("name", "resolve", "/ipns/"+name.String())
|
||||
require.Equal(t, publishPath+"\n", res.Stdout.String())
|
||||
})
|
||||
|
||||
t.Run("Publishing nothing fails", func(t *testing.T) {
|
||||
res := node.RunIPFS("name", "publish")
|
||||
require.Error(t, res.Err)
|
||||
require.Equal(t, 1, res.ExitCode())
|
||||
require.Contains(t, res.Stderr.String(), `argument "ipfs-path" is required`)
|
||||
})
|
||||
|
||||
t.Run("Publishing with IPLD works", func(t *testing.T) {
|
||||
publishPath := "/ipld/" + dagCid + "/thing"
|
||||
res := node.IPFS("name", "publish", "--allow-offline", publishPath)
|
||||
require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name.String(), publishPath), res.Stdout.String())
|
||||
|
||||
res = node.IPFS("name", "resolve", "/ipns/"+name.String())
|
||||
require.Equal(t, publishPath+"\n", res.Stdout.String())
|
||||
})
|
||||
|
||||
publishPath := "/ipfs/" + fixtureCid
|
||||
res := node.IPFS("name", "publish", "--allow-offline", publishPath)
|
||||
require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name.String(), publishPath), res.Stdout.String())
|
||||
|
||||
t.Run("Resolving self offline succeeds (daemon off)", func(t *testing.T) {
|
||||
res = node.IPFS("name", "resolve", "--offline", "/ipns/"+name.String())
|
||||
require.Equal(t, publishPath+"\n", res.Stdout.String())
|
||||
|
||||
// Test without cache.
|
||||
res = node.IPFS("name", "resolve", "--offline", "-n", "/ipns/"+name.String())
|
||||
require.Equal(t, publishPath+"\n", res.Stdout.String())
|
||||
})
|
||||
|
||||
node.StartDaemon()
|
||||
|
||||
t.Run("Resolving self offline succeeds (daemon on)", func(t *testing.T) {
|
||||
res = node.IPFS("name", "resolve", "--offline", "/ipns/"+name.String())
|
||||
require.Equal(t, publishPath+"\n", res.Stdout.String())
|
||||
|
||||
// Test without cache.
|
||||
res = node.IPFS("name", "resolve", "--offline", "-n", "/ipns/"+name.String())
|
||||
require.Equal(t, publishPath+"\n", res.Stdout.String())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
testPublishingWithSelf("default")
|
||||
testPublishingWithSelf("rsa")
|
||||
testPublishingWithSelf("ed25519")
|
||||
|
||||
testPublishWithKey := func(name string, keyArgs ...string) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := makeDaemon(t, nil)
|
||||
|
||||
keyGenArgs := []string{"key", "gen"}
|
||||
keyGenArgs = append(keyGenArgs, keyArgs...)
|
||||
keyGenArgs = append(keyGenArgs, "key")
|
||||
|
||||
res := node.IPFS(keyGenArgs...)
|
||||
key := strings.TrimSpace(res.Stdout.String())
|
||||
|
||||
publishPath := "/ipfs/" + fixtureCid
|
||||
name, err := ipns.NameFromString(key)
|
||||
require.NoError(t, err)
|
||||
|
||||
res = node.IPFS("name", "publish", "--allow-offline", "--key="+key, publishPath)
|
||||
require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name.String(), publishPath), res.Stdout.String())
|
||||
})
|
||||
}
|
||||
|
||||
testPublishWithKey("Publishing with RSA (with b58mh) Key", "--ipns-base=b58mh", "--type=rsa", "--size=2048")
|
||||
testPublishWithKey("Publishing with ED25519 (with b58mh) Key", "--ipns-base=b58mh", "--type=ed25519")
|
||||
testPublishWithKey("Publishing with ED25519 (with base36) Key", "--ipns-base=base36", "--type=ed25519")
|
||||
|
||||
t.Run("Fails to publish in offline mode", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := makeDaemon(t, nil).StartDaemon("--offline")
|
||||
res := node.RunIPFS("name", "publish", "/ipfs/"+fixtureCid)
|
||||
require.Error(t, res.Err)
|
||||
require.Equal(t, 1, res.ExitCode())
|
||||
require.Contains(t, res.Stderr.String(), `can't publish while offline`)
|
||||
})
|
||||
|
||||
t.Run("Publish V2-only record", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
node := makeDaemon(t, nil).StartDaemon()
|
||||
ipnsName := ipns.NameFromPeer(node.PeerID()).String()
|
||||
ipnsPath := ipns.NamespacePrefix + ipnsName
|
||||
publishPath := "/ipfs/" + fixtureCid
|
||||
|
||||
res := node.IPFS("name", "publish", "--ttl=30m", "--v1compat=false", publishPath)
|
||||
require.Equal(t, fmt.Sprintf("Published to %s: %s\n", ipnsName, publishPath), res.Stdout.String())
|
||||
|
||||
res = node.IPFS("name", "resolve", ipnsPath)
|
||||
require.Equal(t, publishPath+"\n", res.Stdout.String())
|
||||
|
||||
res = node.IPFS("routing", "get", ipnsPath)
|
||||
record := res.Stdout.Bytes()
|
||||
|
||||
res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect")
|
||||
out := res.Stdout.String()
|
||||
require.Contains(t, out, "This record was not validated.")
|
||||
require.Contains(t, out, publishPath)
|
||||
require.Contains(t, out, "30m")
|
||||
|
||||
res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--verify="+ipnsPath)
|
||||
out = res.Stdout.String()
|
||||
require.Contains(t, out, "Valid: true")
|
||||
require.Contains(t, out, "Signature Type: V2")
|
||||
require.Contains(t, out, fmt.Sprintf("Protobuf Size: %d", len(record)))
|
||||
})
|
||||
|
||||
t.Run("Publish with TTL and inspect record", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
node := makeDaemon(t, nil).StartDaemon()
|
||||
ipnsPath := ipns.NamespacePrefix + ipns.NameFromPeer(node.PeerID()).String()
|
||||
publishPath := "/ipfs/" + fixtureCid
|
||||
|
||||
_ = node.IPFS("name", "publish", "--ttl=30m", publishPath)
|
||||
res := node.IPFS("routing", "get", ipnsPath)
|
||||
record := res.Stdout.Bytes()
|
||||
|
||||
t.Run("Inspect record shows correct TTL and that it is not validated", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect")
|
||||
out := res.Stdout.String()
|
||||
require.Contains(t, out, "This record was not validated.")
|
||||
require.Contains(t, out, publishPath)
|
||||
require.Contains(t, out, "30m")
|
||||
require.Contains(t, out, "Signature Type: V1+V2")
|
||||
require.Contains(t, out, fmt.Sprintf("Protobuf Size: %d", len(record)))
|
||||
})
|
||||
|
||||
t.Run("Inspect record shows valid with correct name", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
res := node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--enc=json", "--verify="+ipnsPath)
|
||||
val := name.IpnsInspectResult{}
|
||||
err := json.Unmarshal(res.Stdout.Bytes(), &val)
|
||||
require.NoError(t, err)
|
||||
require.True(t, val.Validation.Valid)
|
||||
})
|
||||
|
||||
t.Run("Inspect record shows invalid with wrong name", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
res := node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--enc=json", "--verify=12D3KooWRirYjmmQATx2kgHBfky6DADsLP7ex1t7BRxJ6nqLs9WH")
|
||||
val := name.IpnsInspectResult{}
|
||||
err := json.Unmarshal(res.Stdout.Bytes(), &val)
|
||||
require.NoError(t, err)
|
||||
require.False(t, val.Validation.Valid)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Inspect with verification using wrong RSA key errors", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
node := makeDaemon(t, nil).StartDaemon()
|
||||
|
||||
// Prepare RSA Key 1
|
||||
res := node.IPFS("key", "gen", "--type=rsa", "--size=4096", "key1")
|
||||
key1 := strings.TrimSpace(res.Stdout.String())
|
||||
name1, err := ipns.NameFromString(key1)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Prepare RSA Key 2
|
||||
res = node.IPFS("key", "gen", "--type=rsa", "--size=4096", "key2")
|
||||
key2 := strings.TrimSpace(res.Stdout.String())
|
||||
name2, err := ipns.NameFromString(key2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Publish using Key 1
|
||||
publishPath := "/ipfs/" + fixtureCid
|
||||
res = node.IPFS("name", "publish", "--allow-offline", "--key="+key1, publishPath)
|
||||
require.Equal(t, fmt.Sprintf("Published to %s: %s\n", name1.String(), publishPath), res.Stdout.String())
|
||||
|
||||
// Get IPNS Record
|
||||
res = node.IPFS("routing", "get", ipns.NamespacePrefix+name1.String())
|
||||
record := res.Stdout.Bytes()
|
||||
|
||||
// Validate with correct key succeeds
|
||||
res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--verify="+name1.String(), "--enc=json")
|
||||
val := name.IpnsInspectResult{}
|
||||
err = json.Unmarshal(res.Stdout.Bytes(), &val)
|
||||
require.NoError(t, err)
|
||||
require.True(t, val.Validation.Valid)
|
||||
|
||||
// Validate with wrong key fails
|
||||
res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--verify="+name2.String(), "--enc=json")
|
||||
val = name.IpnsInspectResult{}
|
||||
err = json.Unmarshal(res.Stdout.Bytes(), &val)
|
||||
require.NoError(t, err)
|
||||
require.False(t, val.Validation.Valid)
|
||||
})
|
||||
}
|
||||
@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../
|
||||
require (
|
||||
github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd
|
||||
github.com/golangci/golangci-lint v1.49.0
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191
|
||||
github.com/ipfs/go-cid v0.4.1
|
||||
github.com/ipfs/go-cidutil v0.1.0
|
||||
github.com/ipfs/go-datastore v0.6.0
|
||||
@ -114,6 +114,7 @@ require (
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||
github.com/huin/goupnp v1.2.0 // indirect
|
||||
|
||||
@ -398,6 +398,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
@ -413,8 +415,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
||||
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442 h1:SGbw381zt6c1VFf3QCBaJ+eVJ4AwD9fPaFKFp9U9Apk=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629143123-2d3edc552442/go.mod h1:1qgKq45mPRCxf4ZPoJV2lnXxyxucigILMJOrQrVivv8=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191 h1:oNiEZXJYb4B6zmvUc3F5vvS4xtll8naN8rz1hKftgd4=
|
||||
github.com/ipfs/boxo v0.10.2-0.20230629140307-fdad9f921191/go.mod h1:8IfDmp+FzFGcF4zjAgHMVPpwYw4AjN9ePEzDfkaYJ1w=
|
||||
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
|
||||
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
|
||||
github.com/ipfs/go-block-format v0.1.2 h1:GAjkfhVx1f4YTODS6Esrj1wt2HhrtwTnhEr+DyPUaJo=
|
||||
@ -460,7 +462,7 @@ github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JP
|
||||
github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g=
|
||||
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
|
||||
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
|
||||
github.com/ipfs/go-merkledag v0.10.0 h1:IUQhj/kzTZfam4e+LnaEpoiZ9vZF6ldimVlby+6OXL4=
|
||||
github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY=
|
||||
github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg=
|
||||
github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY=
|
||||
github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg=
|
||||
@ -475,7 +477,8 @@ github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo=
|
||||
github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdmg=
|
||||
github.com/ipfs/iptb-plugins v0.5.0 h1:zEMLlWAb531mLpD36KFy/yc0egT6FkBEHQtdERexNao=
|
||||
github.com/ipfs/iptb-plugins v0.5.0/go.mod h1:/6crDf3s58T70BhZ+m9SyyKpK7VvSDS2Ny4kafxXDp4=
|
||||
github.com/ipld/go-car/v2 v2.9.1-0.20230325062757-fff0e4397a3d h1:22g+x1tgWSXK34i25qjs+afr7basaneEkHaglBshd2g=
|
||||
github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8=
|
||||
github.com/ipld/go-car/v2 v2.10.2-0.20230622090957-499d0c909d33 h1:0OZwzSYWIuiKEOXd/2vm5cMcEmmGLFn+1h6lHELCm3s=
|
||||
github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc=
|
||||
github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s=
|
||||
github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g=
|
||||
|
||||
@ -1,345 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (c) 2014 Jeromy Johnson
|
||||
# MIT Licensed; see the LICENSE file in this repository.
|
||||
#
|
||||
|
||||
test_description="Test ipfs repo operations"
|
||||
|
||||
. lib/test-lib.sh
|
||||
|
||||
test_name_with_self() {
|
||||
SELF_ALG=$1
|
||||
|
||||
test_expect_success "ipfs init (variant self $SELF_ALG)" '
|
||||
export IPFS_PATH="$(pwd)/.ipfs" &&
|
||||
case $SELF_ALG in
|
||||
default)
|
||||
ipfs init --empty-repo=false --profile=test > /dev/null
|
||||
;;
|
||||
rsa)
|
||||
ipfs init --empty-repo=false --profile=test -a=rsa > /dev/null
|
||||
;;
|
||||
ed25519)
|
||||
ipfs init --empty-repo=false --profile=test -a=ed25519 > /dev/null
|
||||
;;
|
||||
esac &&
|
||||
export PEERID=`ipfs key list --ipns-base=base36 -l | grep self | cut -d " " -f1` &&
|
||||
test_check_peerid "${PEERID}"
|
||||
'
|
||||
|
||||
# test publishing a hash
|
||||
|
||||
test_expect_success "'ipfs name publish --allow-offline' succeeds" '
|
||||
ipfs name publish --allow-offline "/ipfs/$HASH_WELCOME_DOCS" >publish_out
|
||||
'
|
||||
|
||||
test_expect_success "publish output looks good" '
|
||||
echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS" >expected1 &&
|
||||
test_cmp expected1 publish_out
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipfs/%s\n" "$HASH_WELCOME_DOCS" >expected2 &&
|
||||
test_cmp expected2 output
|
||||
'
|
||||
|
||||
# test publishing with -Q option
|
||||
|
||||
test_expect_success "'ipfs name publish --quieter' succeeds" '
|
||||
ipfs name publish --allow-offline -Q "/ipfs/$HASH_WELCOME_DOCS" >publish_out
|
||||
'
|
||||
|
||||
test_expect_success "publish --quieter output looks good" '
|
||||
echo "${PEERID}" >expected1 &&
|
||||
test_cmp expected1 publish_out
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipfs/%s\n" "$HASH_WELCOME_DOCS" >expected2 &&
|
||||
test_cmp expected2 output
|
||||
'
|
||||
|
||||
# now test with a path
|
||||
|
||||
test_expect_success "'ipfs name publish --allow-offline' succeeds" '
|
||||
ipfs name publish --allow-offline "/ipfs/$HASH_WELCOME_DOCS/help" >publish_out
|
||||
'
|
||||
|
||||
test_expect_success "publish a path looks good" '
|
||||
echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS/help" >expected3 &&
|
||||
test_cmp expected3 publish_out
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipfs/%s/help\n" "$HASH_WELCOME_DOCS" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
test_expect_success "ipfs cat on published content succeeds" '
|
||||
ipfs cat "/ipfs/$HASH_WELCOME_DOCS/help" >expected &&
|
||||
ipfs cat "/ipns/$PEERID" >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
# publish with an explicit node ID
|
||||
|
||||
test_expect_failure "'ipfs name publish --allow-offline <local-id> <hash>' succeeds" '
|
||||
echo ipfs name publish --allow-offline "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" &&
|
||||
ipfs name publish --allow-offline "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish
|
||||
'
|
||||
|
||||
test_expect_failure "publish with our explicit node ID looks good" '
|
||||
echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS" >expected_node_id_publish &&
|
||||
test_cmp expected_node_id_publish actual_node_id_publish
|
||||
'
|
||||
|
||||
# test publishing with B36CID and B58MH resolve to the same B36CID
|
||||
|
||||
test_expect_success "verify self key output" '
|
||||
B58MH_ID=`ipfs key list --ipns-base=b58mh -l | grep self | cut -d " " -f1` &&
|
||||
B36CID_ID=`ipfs key list --ipns-base=base36 -l | grep self | cut -d " " -f1` &&
|
||||
test_check_peerid "${B58MH_ID}" &&
|
||||
test_check_peerid "${B36CID_ID}"
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name publish --allow-offline --key=<peer-id> <hash>' succeeds" '
|
||||
ipfs name publish --allow-offline --key=${B58MH_ID} "/ipfs/$HASH_WELCOME_DOCS" >b58mh_published_id_base36 &&
|
||||
ipfs name publish --allow-offline --key=${B36CID_ID} "/ipfs/$HASH_WELCOME_DOCS" >base36_published_id_base36 &&
|
||||
ipfs name publish --allow-offline --key=${B58MH_ID} --ipns-base=b58mh "/ipfs/$HASH_WELCOME_DOCS" >b58mh_published_id_b58mh &&
|
||||
ipfs name publish --allow-offline --key=${B36CID_ID} --ipns-base=b58mh "/ipfs/$HASH_WELCOME_DOCS" >base36_published_id_b58mh
|
||||
'
|
||||
|
||||
test_expect_success "publish an explicit node ID as two key in B58MH and B36CID, name looks good" '
|
||||
echo "Published to ${B36CID_ID}: /ipfs/$HASH_WELCOME_DOCS" >expected_published_id_base36 &&
|
||||
echo "Published to ${B58MH_ID}: /ipfs/$HASH_WELCOME_DOCS" >expected_published_id_b58mh &&
|
||||
test_cmp expected_published_id_base36 b58mh_published_id_base36 &&
|
||||
test_cmp expected_published_id_base36 base36_published_id_base36 &&
|
||||
test_cmp expected_published_id_b58mh b58mh_published_id_b58mh &&
|
||||
test_cmp expected_published_id_b58mh base36_published_id_b58mh
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$B36CID_ID" >output
|
||||
'
|
||||
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipfs/%s\n" "$HASH_WELCOME_DOCS" >expected2 &&
|
||||
test_cmp expected2 output
|
||||
'
|
||||
|
||||
# test IPNS + IPLD
|
||||
|
||||
test_expect_success "'ipfs dag put' succeeds" '
|
||||
HELLO_HASH="$(echo "\"hello world\"" | ipfs dag put)" &&
|
||||
OBJECT_HASH="$(echo "{\"thing\": {\"/\": \"${HELLO_HASH}\" }}" | ipfs dag put)"
|
||||
'
|
||||
test_expect_success "'ipfs name publish --allow-offline /ipld/...' succeeds" '
|
||||
test_check_peerid "${PEERID}" &&
|
||||
ipfs name publish --allow-offline "/ipld/$OBJECT_HASH/thing" >publish_out
|
||||
'
|
||||
test_expect_success "publish a path looks good" '
|
||||
echo "Published to ${PEERID}: /ipld/$OBJECT_HASH/thing" >expected3 &&
|
||||
test_cmp expected3 publish_out
|
||||
'
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good (IPNS + IPLD)" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
# test publishing nothing
|
||||
|
||||
test_expect_success "'ipfs name publish' fails" '
|
||||
printf '' | test_expect_code 1 ipfs name publish --allow-offline >publish_out 2>&1
|
||||
'
|
||||
|
||||
test_expect_success "publish output has the correct error" '
|
||||
grep "argument \"ipfs-path\" is required" publish_out
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name publish' fails" '
|
||||
printf '' | test_expect_code 1 ipfs name publish -Q --allow-offline >publish_out 2>&1
|
||||
'
|
||||
|
||||
test_expect_success "publish output has the correct error" '
|
||||
grep "argument \"ipfs-path\" is required" publish_out
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name publish --help' succeeds" '
|
||||
ipfs name publish --help
|
||||
'
|
||||
|
||||
# test offline resolve
|
||||
|
||||
test_expect_success "'ipfs name resolve --offline' succeeds" '
|
||||
ipfs name resolve --offline "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good (offline resolve)" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve --offline -n' succeeds" '
|
||||
ipfs name resolve --offline -n "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good (offline resolve, -n)" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
test_launch_ipfs_daemon
|
||||
|
||||
test_expect_success "'ipfs name resolve --offline' succeeds" '
|
||||
ipfs name resolve --offline "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good (with daemon)" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve --offline -n' succeeds" '
|
||||
ipfs name resolve --offline -n "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good (with daemon, -n)" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
test_expect_success "empty request to name publish doesn't panic and returns error" '
|
||||
curl -X POST "http://$API_ADDR/api/v0/name/publish" > curl_out || true &&
|
||||
grep "argument \"ipfs-path\" is required" curl_out
|
||||
'
|
||||
|
||||
# Test Publishing with TTL and Inspecting Records
|
||||
test_expect_success "'ipfs name publish --ttl=30m' succeeds" '
|
||||
ipfs name publish --ttl=30m --allow-offline "/ipfs/$HASH_WELCOME_DOCS"
|
||||
'
|
||||
|
||||
test_expect_success "retrieve IPNS key for further inspection" '
|
||||
ipfs routing get "/ipns/$PEERID" > ipns_record
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name inspect' has correct TTL (30m)" '
|
||||
ipfs name inspect < ipns_record > verify_output &&
|
||||
test_should_contain "This record was not validated." verify_output &&
|
||||
test_should_contain "$HASH_WELCOME_DOCS" verify_output &&
|
||||
test_should_contain "1800000000000" verify_output
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name inspect --verify' has '.Validation.Validity' set to 'true' with correct Peer ID" '
|
||||
ipfs name inspect --verify $PEERID --enc json < ipns_record | jq -e ".Validation.Valid == true and .Entry.TTL == .Entry.Data.TTL"
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name inspect --verify' has '.Validation.Validity' set to 'false' with incorrect Peer ID" '
|
||||
ipfs name inspect --verify 12D3KooWRirYjmmQATx2kgHBfky6DADsLP7ex1t7BRxJ6nqLs9WH --enc json < ipns_record | jq -e ".Validation.Valid == false"
|
||||
'
|
||||
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
# Test daemon in offline mode
|
||||
test_launch_ipfs_daemon_without_network
|
||||
|
||||
test_expect_success "'ipfs name publish' fails offline mode" '
|
||||
test_expect_code 1 ipfs name publish "/ipfs/$HASH_WELCOME_DOCS"
|
||||
'
|
||||
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
test_expect_success "clean up ipfs dir" '
|
||||
rm -rf "$IPFS_PATH"
|
||||
'
|
||||
}
|
||||
test_name_with_self 'default'
|
||||
test_name_with_self 'rsa'
|
||||
test_name_with_self 'ed25519'
|
||||
|
||||
test_name_with_key() {
|
||||
GEN_ALG=$1
|
||||
|
||||
test_expect_success "ipfs init (key variant $GEN_ALG)" '
|
||||
export IPFS_PATH="$(pwd)/.ipfs" &&
|
||||
ipfs init --empty-repo=false --profile=test > /dev/null
|
||||
'
|
||||
|
||||
test_expect_success "'prepare keys" '
|
||||
case $GEN_ALG in
|
||||
rsa)
|
||||
export KEY=`ipfs key gen --ipns-base=b58mh --type=rsa --size=2048 key` &&
|
||||
export KEY_B36CID=`ipfs key list --ipns-base=base36 -l | grep key | cut -d " " -f1`
|
||||
;;
|
||||
ed25519_b58)
|
||||
export KEY=`ipfs key gen --ipns-base=b58mh --type=ed25519 key`
|
||||
export KEY_B36CID=`ipfs key list --ipns-base=base36 -l | grep key | cut -d " " -f1`
|
||||
;;
|
||||
ed25519_b36)
|
||||
export KEY=`ipfs key gen --ipns-base=base36 --type=ed25519 key`
|
||||
export KEY_B36CID=$KEY
|
||||
;;
|
||||
esac &&
|
||||
test_check_peerid "${KEY}"
|
||||
'
|
||||
|
||||
# publish with an explicit node ID as key name
|
||||
|
||||
test_expect_success "'ipfs name publish --allow-offline --key=<peer-id> <hash>' succeeds" '
|
||||
ipfs name publish --allow-offline --key=${KEY} "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish
|
||||
'
|
||||
|
||||
test_expect_success "publish an explicit node ID as key name looks good" '
|
||||
echo "Published to ${KEY_B36CID}: /ipfs/$HASH_WELCOME_DOCS" >expected_node_id_publish &&
|
||||
test_cmp expected_node_id_publish actual_node_id_publish
|
||||
'
|
||||
|
||||
# cleanup
|
||||
test_expect_success "clean up ipfs dir" '
|
||||
rm -rf "$IPFS_PATH"
|
||||
'
|
||||
}
|
||||
test_name_with_key 'rsa'
|
||||
test_name_with_key 'ed25519_b58'
|
||||
test_name_with_key 'ed25519_b36'
|
||||
|
||||
|
||||
# `ipfs name inspect --verify` using the wrong RSA key should not succeed
|
||||
|
||||
test_init_ipfs --empty-repo=false
|
||||
test_launch_ipfs_daemon
|
||||
|
||||
test_expect_success "prepare RSA keys" '
|
||||
export KEY_1=`ipfs key gen --type=rsa --size=4096 key1` &&
|
||||
export KEY_2=`ipfs key gen --type=rsa --size=4096 key2` &&
|
||||
export PEERID_1=`ipfs key list --ipns-base=base36 -l | grep key1 | cut -d " " -f1` &&
|
||||
export PEERID_2=`ipfs key list --ipns-base=base36 -l | grep key2 | cut -d " " -f1`
|
||||
'
|
||||
|
||||
test_expect_success "ipfs name publish --allow-offline --key=<peer-id> <hash>' succeeds" '
|
||||
ipfs name publish --allow-offline --key=${KEY_1} "/ipfs/$( echo "helloworld" | ipfs add --inline -q )" &&
|
||||
ipfs routing get "/ipns/$PEERID_1" > ipns_record
|
||||
'
|
||||
|
||||
test_expect_success "ipfs name inspect --verify' has '.Validation.Validity' set to 'true' with correct Peer ID" '
|
||||
ipfs name inspect --verify $PEERID_1 --enc json < ipns_record | jq -e ".Validation.Valid == true"
|
||||
'
|
||||
|
||||
test_expect_success "ipfs name inspect --verify' has '.Validation.Validity' set to 'false' when we verify the wrong Peer ID" '
|
||||
ipfs name inspect --verify $PEERID_2 --enc json < ipns_record | jq -e ".Validation.Valid == false"
|
||||
'
|
||||
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
test_done
|
||||
@ -124,8 +124,8 @@ ipfs_bitswap_sent_all_blocks_bytes_count
|
||||
ipfs_bitswap_sent_all_blocks_bytes_sum
|
||||
ipfs_bitswap_want_blocks_total
|
||||
ipfs_bitswap_wantlist_total
|
||||
ipfs_bs_cache_arc_hits_total
|
||||
ipfs_bs_cache_arc_total
|
||||
ipfs_bs_cache_boxo_blockstore_cache_hits
|
||||
ipfs_bs_cache_boxo_blockstore_cache_total
|
||||
ipfs_fsrepo_datastore_batchcommit_errors_total
|
||||
ipfs_fsrepo_datastore_batchcommit_latency_seconds_bucket
|
||||
ipfs_fsrepo_datastore_batchcommit_latency_seconds_count
|
||||
|
||||
@ -29,7 +29,7 @@ test_expect_success "no panic traces on daemon" '
|
||||
|
||||
test_expect_success "metrics work" '
|
||||
curl -X POST "$API_ADDR/debug/metrics/prometheus" > pro_data &&
|
||||
grep "ipfs_bs_cache_arc_hits_total" < pro_data ||
|
||||
grep "ipfs_bs_cache_boxo_blockstore_cache_total" < pro_data ||
|
||||
test_fsh cat pro_data
|
||||
'
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
var CurrentCommit string
|
||||
|
||||
// CurrentVersionNumber is the current application's version literal
|
||||
const CurrentVersionNumber = "0.21.0"
|
||||
const CurrentVersionNumber = "0.22.0-dev"
|
||||
|
||||
const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user