Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate go-unixfsnode #25

Merged
merged 54 commits into from
Jan 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
1e82733
first commit
hannahhoward Mar 5, 2021
cd049e0
feat(unixfsnode): initial implementation
hannahhoward Mar 5, 2021
eabd475
feat(data): add unixfs data node decoding
hannahhoward Mar 31, 2021
8c66104
feat(hamt): add hamt implementation
hannahhoward Apr 1, 2021
d37f474
feat(directory): seperate directory implementation
hannahhoward Apr 1, 2021
34a81a1
fix(unixfsnode): have reifier add path selection to normal nodes
hannahhoward Apr 1, 2021
1e0dabf
fix(unixfsnode): cleanup from comments
hannahhoward Apr 2, 2021
45a1a9a
feat(reification): use new prime node reification
hannahhoward Apr 2, 2021
f25054d
fix(unixfsnode): respond to PR comments
hannahhoward Apr 3, 2021
af10b84
Merge pull request ipfs/go-unixfsnode#4 from ipfs/feat/support-hamt
hannahhoward Apr 4, 2021
50aff33
feat(reifier): don't error on missing reification for now
hannahhoward Apr 5, 2021
84c68c4
data: update ipld-prime version to fix codegen issues
mvdan Jun 19, 2021
bc6ef62
Merge pull request ipfs/go-unixfsnode#6 from mvdan/ipld-gen
marten-seemann Jun 19, 2021
497695c
fix staticcheck
marten-seemann Jun 19, 2021
d131639
Merge pull request ipfs/go-unixfsnode#7 from ipfs/fix-staticcheck
marten-seemann Jun 19, 2021
4516ade
fix go vet
marten-seemann Jun 19, 2021
4e99484
Merge pull request ipfs/go-unixfsnode#5 from ipfs/web3-bot/sync
marten-seemann Jun 19, 2021
e2fc731
make UnixFSHAMTShard implement the ADL interface (#11)
aschmahmann Sep 27, 2021
1fbc9e6
Add builder for unixfs dags (#12)
willscott Oct 18, 2021
84ecfe7
Add ADL/single-node-view of a full unixFS file. (#14)
willscott Nov 4, 2021
4d9dcdd
handle empty files (#15)
willscott Nov 5, 2021
c587c00
add license (#17)
willscott Dec 2, 2021
f3fe24f
chore: update deps
aschmahmann Dec 21, 2021
9b82c04
feat(unixfsnode): add utils for signalling for selectors
hannahhoward Jan 10, 2022
abdd6a5
Merge pull request ipfs/go-unixfsnode#20 from ipfs/feat/update-deps
hannahhoward Jan 13, 2022
ee986c8
fix: encode Tsize correctly everywhere (using wraped LinkSystem)
rvagg Jan 21, 2022
1690969
fix: more Tsize fixes, fix HAMT and make it match go-unixfs output
rvagg Jan 21, 2022
79823b0
fix: add extra test to span the shard/no-shard boundary
rvagg Jan 24, 2022
1790dea
add AsLargeBytes support to unixfs files (#24)
willscott Mar 3, 2022
ab5e7d1
fix(unixfsnode): add unixfs to path tail
hannahhoward Mar 7, 2022
7407986
Roundtrip test for partial file reads and traversals
willscott Mar 3, 2022
c08b9d2
add doc to make linter happier
willscott Mar 3, 2022
3353979
Merge pull request ipfs/go-unixfsnode#26 from ipfs/partial-file-test
hannahhoward Mar 9, 2022
7ec18e1
add quickbuilder helper to approximate test creation commonly used wi…
willscott May 2, 2022
8e150bf
chore: remove Stebalien/go-bitfield in favour of ipfs/go-bitfield
rvagg May 2, 2022
8f89eac
Merge pull request ipfs/go-unixfsnode#32 from ipfs/quickbuilder
willscott May 4, 2022
fb809f9
test for reader / sizing behavior on large files
willscott Aug 14, 2022
921351a
review comments
willscott Aug 20, 2022
b5a3ecd
fix nit. clearer name
willscott Aug 20, 2022
5031cf0
split large file test to not run with race detector, sine that's too …
willscott Aug 20, 2022
d6e5e1e
Merge pull request ipfs/go-unixfsnode#34 from ipfs/largeFileReads
willscott Aug 22, 2022
bf32171
bump go.mod to Go 1.18 and run go fix
web3-bot Aug 24, 2022
0059950
run gofmt -s
web3-bot Aug 24, 2022
a7ae3e7
fix: remove use of ioutil
rvagg Aug 24, 2022
4470d12
add an ADL to preload hamt loading
willscott Oct 8, 2022
7957235
remaining linking
willscott Oct 8, 2022
e438fa7
Update file/file.go
willscott Oct 15, 2022
d91d973
expand readme a bit
willscott Oct 15, 2022
a48c4ab
Merge pull request ipfs/go-unixfsnode#38 from ipfs/feat/preload
willscott Oct 15, 2022
971cdf4
fix a possible `index out of range` crash
bachue Jan 9, 2023
f46daff
Merge pull request ipfs/go-unixfsnode#39 from bachue/fix/crash
willscott Jan 9, 2023
2fed26c
Merge commits from ipfs/go-unixfsnode/main
hacdias Jan 12, 2023
0d10ff9
chore: go mod tidy
hacdias Jan 12, 2023
6f33aab
chore: replace import paths
hacdias Jan 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 44 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,84 @@ require (
github.com/benbjohnson/clock v1.3.0
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3
github.com/gorilla/mux v1.8.0
github.com/ipfs/go-bitfield v1.0.0
github.com/ipfs/go-cid v0.3.2
github.com/ipfs/go-ipfs-chunker v0.0.5
github.com/ipfs/go-ipfs-util v0.0.2
github.com/ipfs/go-ipld-format v0.4.0
github.com/ipfs/go-ipns v0.3.0
github.com/ipfs/go-log/v2 v2.5.1
github.com/ipfs/go-merkledag v0.9.0
github.com/ipfs/go-unixfs v0.4.1
github.com/ipld/go-car/v2 v2.5.1
github.com/ipld/go-codec-dagpb v1.5.0
github.com/ipld/go-ipld-prime v0.19.0
github.com/libp2p/go-libp2p v0.23.4
github.com/libp2p/go-libp2p-record v0.2.0
github.com/multiformats/go-multiaddr v0.8.0
github.com/multiformats/go-multibase v0.1.1
github.com/multiformats/go-multicodec v0.6.0
github.com/multiformats/go-multihash v0.2.1
github.com/samber/lo v1.36.0
github.com/spaolacci/murmur3 v1.1.0
github.com/stretchr/testify v1.8.1
go.opencensus.io v0.23.0
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab
google.golang.org/protobuf v1.28.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/ipfs/go-ipfs-util v0.0.2 // indirect
github.com/ipld/go-ipld-prime v0.9.0 // indirect
github.com/klauspost/cpuid/v2 v2.1.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/ipfs/bbloom v0.0.4 // indirect
github.com/ipfs/go-block-format v0.0.3 // indirect
github.com/ipfs/go-blockservice v0.5.0 // indirect
github.com/ipfs/go-datastore v0.6.0 // indirect
github.com/ipfs/go-ipfs-blockstore v1.2.0 // 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-exchange-offline v0.3.0 // indirect
github.com/ipfs/go-ipld-cbor v0.0.6 // indirect
github.com/ipfs/go-ipld-legacy v0.1.1 // indirect
github.com/ipfs/go-log v1.0.5 // indirect
github.com/ipfs/go-metrics-interface v0.0.1 // indirect
github.com/ipfs/go-unixfsnode v1.5.1 // indirect
github.com/ipfs/go-verifcid v0.0.2 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect
github.com/klauspost/cpuid/v2 v2.1.2 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-openssl v0.1.0 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-pointer v0.0.1 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.1.0 // indirect
github.com/multiformats/go-multicodec v0.6.0 // indirect
github.com/multiformats/go-varint v0.0.6 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1 // indirect
github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect
github.com/whyrusleeping/cbor-gen v0.0.0-20221220214510-0333c149dec0 // indirect
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect
go.opentelemetry.io/otel v1.7.0 // indirect
go.opentelemetry.io/otel/trace v1.7.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.23.0 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.1.7 // indirect
)
186 changes: 177 additions & 9 deletions go.sum

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions unixfs/node/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# go-unixfsnode

This is an IPLD ADL that provides string based pathing for protobuf nodes. The top level node behaves like a map where LookupByString returns the Hash property on the Link in the protobufs list of Links whos Name property matches the key. This should enable selector traversals that work based of paths.

Note that while it works internally with go-codec-dagpb, the Reify method (used to get a UnixFSNode from a DagPB node should actually work successfully with go-ipld-prime-proto nodes)

## Usage

The primary interaction with this package is to register an ADL on a link system. This is done with via a helper method.

```go
AddUnixFSReificationToLinkSystem(lsys *ipld.LinkSystem)
```

For link systems which have UnixFS reification registered, two ADLs will be available to the [`InterpretAs`](https://ipld.io/specs/selectors/) selector: 'unixfs' and 'unixfs-preload'. The different between these two ADLs is that the preload variant will access all blocks within a UnixFS Object (file or directory) when that object is accessed by a selector traversal. The non-preload variant in contrast will only access the subset of blocks strictly needed for the traversal. In practice, this means the subset of a sharded directory needed to access a specific file, or the sub-range of a file directly accessed by a range selector.


## License

Apache-2.0/MIT © Protocol Labs
142 changes: 142 additions & 0 deletions unixfs/node/data/builder/builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package builder

import (
"errors"
"strconv"
"time"

"github.com/ipfs/go-libipfs/unixfs/node/data"
"github.com/ipld/go-ipld-prime"
"github.com/ipld/go-ipld-prime/fluent/qp"
)

// BuildUnixFS provides a clean, validated interface to building data structures
// that match the UnixFS protobuf encoded in the Data member of a ProtoNode
// with sensible defaults
//
// smallFileData, err := BuildUnixFS(func(b *Builder) {
// Data(b, []byte{"hello world"})
// Mtime(b, func(tb TimeBuilder) {
// Time(tb, time.Now())
// })
// })
func BuildUnixFS(fn func(*Builder)) (data.UnixFSData, error) {
nd, err := qp.BuildMap(data.Type.UnixFSData, -1, func(ma ipld.MapAssembler) {
b := &Builder{MapAssembler: ma}
fn(b)
if !b.hasBlockSizes {
qp.MapEntry(ma, data.Field__BlockSizes, qp.List(0, func(ipld.ListAssembler) {}))
}
if !b.hasDataType {
qp.MapEntry(ma, data.Field__DataType, qp.Int(data.Data_File))
}
})
if err != nil {
return nil, err
}
return nd.(data.UnixFSData), nil
}

// Builder is an interface for making UnixFS data nodes
type Builder struct {
ipld.MapAssembler
hasDataType bool
hasBlockSizes bool
}

// DataType sets the default on a builder for a UnixFS node - default is File
func DataType(b *Builder, dataType int64) {
_, ok := data.DataTypeNames[dataType]
if !ok {
panic(data.ErrInvalidDataType{DataType: dataType})
}
qp.MapEntry(b.MapAssembler, data.Field__DataType, qp.Int(dataType))
b.hasDataType = true
}

// Data sets the data member inside the UnixFS data
func Data(b *Builder, dataBytes []byte) {
qp.MapEntry(b.MapAssembler, data.Field__Data, qp.Bytes(dataBytes))
}

// FileSize sets the file size which should be the size of actual bytes underneath
// this node for large files, w/o additional bytes to encode intermediate nodes
func FileSize(b *Builder, fileSize uint64) {
qp.MapEntry(b.MapAssembler, data.Field__FileSize, qp.Int(int64(fileSize)))
}

// BlockSizes encodes block sizes for each child node
func BlockSizes(b *Builder, blockSizes []uint64) {
qp.MapEntry(b.MapAssembler, data.Field__BlockSizes, qp.List(int64(len(blockSizes)), func(la ipld.ListAssembler) {
for _, bs := range blockSizes {
qp.ListEntry(la, qp.Int(int64(bs)))
}
}))
b.hasBlockSizes = true
}

// HashType sets the hash function for this node -- only applicable to HAMT
func HashType(b *Builder, hashType uint64) {
qp.MapEntry(b.MapAssembler, data.Field__HashType, qp.Int(int64(hashType)))
}

// Fanout sets the fanout in a HAMT tree
func Fanout(b *Builder, fanout uint64) {
qp.MapEntry(b.MapAssembler, data.Field__Fanout, qp.Int(int64(fanout)))
}

// Permissions sets file permissions for the Mode member of the UnixFS node
func Permissions(b *Builder, mode int) {
mode = mode & 0xFFF
qp.MapEntry(b.MapAssembler, data.Field__Mode, qp.Int(int64(mode)))
}

func parseModeString(modeString string) (uint64, error) {
if len(modeString) > 0 && modeString[0] == '0' {
return strconv.ParseUint(modeString, 8, 32)
}
return strconv.ParseUint(modeString, 10, 32)
}

// PermissionsString sets file permissions for the Mode member of the UnixFS node,
// parsed from a typical octect encoded permission string (eg '0755')
func PermissionsString(b *Builder, modeString string) {
mode64, err := parseModeString(modeString)
if err != nil {
panic(err)
}
mode64 = mode64 & 0xFFF
qp.MapEntry(b.MapAssembler, data.Field__Mode, qp.Int(int64(mode64)))
}

// Mtime sets the modification time for this node using the time builder interface
// and associated methods
func Mtime(b *Builder, fn func(tb TimeBuilder)) {
qp.MapEntry(b.MapAssembler, data.Field__Mtime, qp.Map(-1, func(ma ipld.MapAssembler) {
fn(ma)
}))
}

// TimeBuilder is a simple interface for constructing the time member of UnixFS data
type TimeBuilder ipld.MapAssembler

// Time sets the modification time from a golang time value
func Time(ma TimeBuilder, t time.Time) {
Seconds(ma, t.Unix())
FractionalNanoseconds(ma, int32(t.Nanosecond()))
}

// Seconds sets the seconds for a modification time
func Seconds(ma TimeBuilder, seconds int64) {
qp.MapEntry(ma, data.Field__Seconds, qp.Int(seconds))

}

// FractionalNanoseconds sets the nanoseconds for a modification time (must
// be between 0 & a billion)
func FractionalNanoseconds(ma TimeBuilder, nanoseconds int32) {
if nanoseconds < 0 || nanoseconds > 999999999 {
panic(errors.New("mtime-nsecs must be within the range [0,999999999]"))
}
qp.MapEntry(ma, data.Field__Nanoseconds, qp.Int(int64(nanoseconds)))
}
Loading