Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ go 1.24
toolchain go1.24.1

require (
blobcache.io/blobcache v0.0.0-20250921182839-f19bbb53bbb0
blobcache.io/blobcache v0.0.0-20250930200349-575026beb251
github.com/cloudflare/circl v1.6.1
github.com/cockroachdb/pebble v1.1.5
github.com/dchest/siphash v1.2.3
github.com/fatih/color v1.13.0
github.com/hashicorp/golang-lru v1.0.2
Expand All @@ -34,6 +33,7 @@ require (
github.com/cockroachdb/errors v1.11.3 // indirect
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v1.1.5 // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand All @@ -48,6 +48,7 @@ require (
github.com/google/btree v1.1.2 // indirect
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/klauspost/compress v1.16.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
blobcache.io/blobcache v0.0.0-20250921182839-f19bbb53bbb0 h1:B9TaQ2zZl+wFxVP5j2cDXPnohQI/nkDgP+aot3RO45I=
blobcache.io/blobcache v0.0.0-20250921182839-f19bbb53bbb0/go.mod h1:MnHcXXl8RdF+cdeu4fb0baeC6ygbZ63J1ILUHo4Il9w=
blobcache.io/blobcache v0.0.0-20250930200349-575026beb251 h1:8yJWc5mmCIFz3VMsXAVWn4fhMrmLO9T0IdFPK0sSDWc=
blobcache.io/blobcache v0.0.0-20250930200349-575026beb251/go.mod h1:agKWYXx2iGHlViL07NBDrVVT8itffX8tG3Y2vYEGFUA=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
Expand Down Expand Up @@ -97,6 +97,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
Expand Down
3 changes: 0 additions & 3 deletions src/branches/testsuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

func TestSpace(t *testing.T, newSpace func(t testing.TB) Space) {
t.Run("CreateGet", func(t *testing.T) {
t.Parallel()
ctx := testutil.Context(t)
x := newSpace(t)
b, err := x.Get(ctx, "test")
Expand All @@ -23,7 +22,6 @@ func TestSpace(t *testing.T, newSpace func(t testing.TB) Space) {
require.NotNil(t, b)
})
t.Run("List", func(t *testing.T) {
//t.Parallel()
ctx := testutil.Context(t)
x := newSpace(t)
const N = 20
Expand All @@ -38,7 +36,6 @@ func TestSpace(t *testing.T, newSpace func(t testing.TB) Space) {
require.Len(t, names, N)
})
t.Run("Delete", func(t *testing.T) {
t.Parallel()
ctx := testutil.Context(t)
x := newSpace(t)
var err error
Expand Down
2 changes: 1 addition & 1 deletion src/branches/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func CleanupVolume(ctx context.Context, vol Volume) error {

func filterStore(ctx context.Context, s cadata.Store, set cadata.Set) (int, error) {
var count int
err := cadata.ForEach(ctx, s, cadata.Span{}, func(id cadata.ID) error {
err := cadata.ForEach(ctx, s, cadata.Span{}, func(id blobcache.CID) error {
exists, err := set.Exists(ctx, id)
if err != nil {
return err
Expand Down
23 changes: 13 additions & 10 deletions src/gdat/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ import (
"io"
"math"

"blobcache.io/blobcache/src/blobcache"
"go.brendoncarroll.net/state/cadata"
"go.brendoncarroll.net/stdctx/logctx"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/chacha20"

"github.com/gotvc/got/src/internal/stores"
)

func Hash(x []byte) cadata.ID {
return blake2b.Sum256(x)
func Hash(x []byte) blobcache.CID {
return stores.Hash(x)
}

// DeriveKey uses the blake2b XOF to fill out.
Expand Down Expand Up @@ -52,20 +55,20 @@ func DeriveStream(secret *[32]byte, additional []byte) io.Reader {
}

// KeyFunc produces a key for a given blob
type KeyFunc func(ptextHash cadata.ID) DEK
type KeyFunc func(ptextHash blobcache.CID) DEK

// SaltedConvergent uses salt to generate convergent keys for each blob.
func SaltedConvergent(salt *[32]byte) KeyFunc {
salt = cloneSalt(salt)
return func(ptextHash cadata.ID) DEK {
return func(ptextHash blobcache.CID) DEK {
dek := DEK{}
DeriveKey(dek[:], salt, ptextHash[:])
return dek
}
}

// Convergent generates a DEK depending only on ptextHash
func Convergent(ptextHash cadata.ID) DEK {
func Convergent(ptextHash blobcache.CID) DEK {
return DEK(ptextHash)
}

Expand All @@ -77,26 +80,26 @@ func (*DEK) String() string {
return "{ 32 byte DEK }"
}

func (a *Machine) postEncrypt(ctx context.Context, s cadata.Poster, keyFunc KeyFunc, data []byte) (cadata.ID, *DEK, error) {
func (a *Machine) postEncrypt(ctx context.Context, s stores.Writing, keyFunc KeyFunc, data []byte) (blobcache.CID, *DEK, error) {
dek := keyFunc(Hash(data))
ctext := a.acquire(s.MaxSize())
defer a.release(ctext)
n := cryptoXOR(dek, ctext, data)
id, err := s.Post(ctx, ctext[:n])
if err != nil {
return cadata.ID{}, nil, err
return blobcache.CID{}, nil, err
}
return id, &dek, nil
}

func getDecrypt(ctx context.Context, s cadata.Getter, dek DEK, id cadata.ID, buf []byte) (int, error) {
func getDecrypt(ctx context.Context, s stores.Reading, dek DEK, id blobcache.CID, buf []byte) (int, error) {
n, err := s.Get(ctx, id, buf)
if err != nil {
return 0, err
}
data := buf[:n]
if err := cadata.Check(s.Hash, id, data); err != nil {
logctx.Errorf(ctx, "len(data)=%d HAVE: %v WANT: %v", len(data), id, s.Hash(data))
if err := cadata.Check(Hash, id, data); err != nil {
logctx.Errorf(ctx, "len(data)=%d HAVE: %v WANT: %v", len(data), id, Hash(data))
return 0, err
}
cryptoXOR(dek, data, data)
Expand Down
13 changes: 4 additions & 9 deletions src/gdat/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@ import (
"context"
"sync"

"github.com/gotvc/got/src/internal/stores"
lru "github.com/hashicorp/golang-lru"
"go.brendoncarroll.net/state/cadata"
)

type (
Getter = cadata.Getter
Store = cadata.Store
)

type Option = func(*Machine)
Expand Down Expand Up @@ -56,7 +51,7 @@ func NewMachine(opts ...Option) *Machine {
return o
}

func (a *Machine) Post(ctx context.Context, s cadata.Poster, data []byte) (*Ref, error) {
func (a *Machine) Post(ctx context.Context, s stores.Writing, data []byte) (*Ref, error) {
id, dek, err := a.postEncrypt(ctx, s, a.kf, data)
if err != nil {
return nil, err
Expand All @@ -67,7 +62,7 @@ func (a *Machine) Post(ctx context.Context, s cadata.Poster, data []byte) (*Ref,
}, nil
}

func (a *Machine) GetF(ctx context.Context, s Getter, ref Ref, fn func(data []byte) error) error {
func (a *Machine) GetF(ctx context.Context, s stores.Reading, ref Ref, fn func(data []byte) error) error {
if data := a.checkCache(ref); data != nil {
return fn(data)
}
Expand All @@ -81,7 +76,7 @@ func (a *Machine) GetF(ctx context.Context, s Getter, ref Ref, fn func(data []by
return fn(data)
}

func (a *Machine) Read(ctx context.Context, s Getter, ref Ref, buf []byte) (int, error) {
func (a *Machine) Read(ctx context.Context, s stores.Reading, ref Ref, buf []byte) (int, error) {
return getDecrypt(ctx, s, ref.DEK, ref.CID, buf)
}

Expand Down
14 changes: 8 additions & 6 deletions src/gdat/refs.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@ import (
"encoding/base64"
"fmt"

"blobcache.io/blobcache/src/blobcache"
"github.com/gotvc/got/src/internal/metrics"
"github.com/gotvc/got/src/internal/stores"
"go.brendoncarroll.net/state/cadata"
)

const (
Base64Alphabet = cadata.Base64Alphabet
RefSize = cadata.IDSize + DEKSize
RefSize = blobcache.CIDSize + DEKSize
)

var codec = base64.NewEncoding(Base64Alphabet).WithPadding(base64.NoPadding)

type Ref struct {
CID cadata.ID
CID blobcache.CID
DEK DEK
}

Expand All @@ -34,8 +36,8 @@ func (r *Ref) Unmarshal(data []byte) error {
if len(data) != RefSize {
return fmt.Errorf("invalid ref length: %d", len(data))
}
copy(r.CID[:], data[:cadata.IDSize])
copy(r.DEK[:], data[cadata.IDSize:])
copy(r.CID[:], data[:blobcache.CIDSize])
copy(r.DEK[:], data[blobcache.CIDSize:])
return nil
}

Expand Down Expand Up @@ -120,7 +122,7 @@ func Equal(a, b Ref) bool {
}

// Copy copies the data at ref from src to dst.
func Copy(ctx context.Context, src cadata.Getter, dst cadata.Poster, ref *Ref) error {
func Copy(ctx context.Context, src stores.Reading, dst stores.Writing, ref *Ref) error {
defer metrics.AddInt(ctx, "blob_copy", 1, "blobs")
return cadata.Copy(ctx, dst, src, ref.CID)
return stores.Copy(ctx, src, dst, ref.CID)
}
5 changes: 3 additions & 2 deletions src/gotfs/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/gotvc/got/src/gotfs/gotlob"
"github.com/gotvc/got/src/gotkv"
"github.com/gotvc/got/src/internal/stores"
"go.brendoncarroll.net/state/cadata"
)

Expand All @@ -20,13 +21,13 @@ type GetPostExister interface {
type Builder struct {
a *Machine
ctx context.Context
ms GetPostExister
ms stores.RW

dirStack []string
b *gotlob.Builder
}

func (a *Machine) NewBuilder(ctx context.Context, ms, ds GetPostExister) *Builder {
func (a *Machine) NewBuilder(ctx context.Context, ms, ds stores.RW) *Builder {
b := &Builder{
a: a,
ctx: ctx,
Expand Down
3 changes: 2 additions & 1 deletion src/gotfs/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strconv"
"testing"

"github.com/gotvc/got/src/internal/stores"
"github.com/gotvc/got/src/internal/testutil"
"github.com/stretchr/testify/require"
"go.brendoncarroll.net/state/cadata"
Expand Down Expand Up @@ -50,6 +51,6 @@ func TestBuilderSmallFiles(t *testing.T) {

func setup(t testing.TB) (context.Context, *Machine, *cadata.MemStore) {
op := NewMachine()
s := cadata.NewMem(cadata.DefaultHash, DefaultMaxBlobSize)
s := stores.NewMem()
return testutil.Context(t), op, s
}
4 changes: 2 additions & 2 deletions src/gotfs/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,11 @@ func (a *Machine) addPrefix(root Root, p string) gotkv.Root {

// MaxInfo returns the maximum path and the corresponding Info for the path.
// If no Info entry can be found MaxInfo returns ("", nil, nil)
func (a *Machine) MaxInfo(ctx context.Context, ms cadata.Store, root Root, span Span) (string, *Info, error) {
func (a *Machine) MaxInfo(ctx context.Context, ms stores.RW, root Root, span Span) (string, *Info, error) {
return a.maxInfo(ctx, ms, root.ToGotKV(), span)
}

func (a *Machine) maxInfo(ctx context.Context, ms cadata.Getter, root gotkv.Root, span Span) (string, *Info, error) {
func (a *Machine) maxInfo(ctx context.Context, ms stores.RW, root gotkv.Root, span Span) (string, *Info, error) {
ent, err := a.gotkv.MaxEntry(ctx, ms, root, span)
if err != nil {
return "", nil, err
Expand Down
9 changes: 5 additions & 4 deletions src/gotkv/gotkv.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"

"blobcache.io/blobcache/src/blobcache"
"github.com/gotvc/got/src/gdat"
"github.com/gotvc/got/src/gotkv/kvstreams"
"github.com/gotvc/got/src/gotkv/ptree"
Expand All @@ -18,9 +19,9 @@ import (
)

type (
Getter = cadata.Getter
Store = cadata.Store
ID = cadata.ID
Getter = stores.Reading
Store = stores.RWD
ID = blobcache.CID
Ref = gdat.Ref

Entry = kvstreams.Entry
Expand Down Expand Up @@ -197,7 +198,7 @@ func do(ctx context.Context, rp ptree.ReadParams[Entry, Ref], x ptree.Root[Entry

type ptreeGetter struct {
ag *gdat.Machine
s cadata.Getter
s stores.Reading
}

func (s *ptreeGetter) Get(ctx context.Context, ref Ref, buf []byte) (int, error) {
Expand Down
3 changes: 2 additions & 1 deletion src/gotkv/gotkv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"testing"

"github.com/gotvc/got/src/internal/stores"
"github.com/gotvc/got/src/internal/testutil"
"github.com/stretchr/testify/require"
"go.brendoncarroll.net/state/cadata"
Expand Down Expand Up @@ -71,7 +72,7 @@ func TestPutGetMany(t *testing.T) {
func testSetup(t *testing.T) (context.Context, cadata.Store, *Root) {
ctx := testutil.Context(t)
ag := newTestMachine(t)
s := cadata.NewMem(cadata.DefaultHash, cadata.DefaultMaxSize)
s := stores.NewMem()
x, err := ag.NewEmpty(ctx, s)
require.NoError(t, err)
return ctx, s, x
Expand Down
4 changes: 2 additions & 2 deletions src/gotkv/kv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import (
"strconv"
"testing"

"github.com/gotvc/got/src/internal/stores"
"github.com/gotvc/got/src/internal/testutil"
"github.com/stretchr/testify/require"
"go.brendoncarroll.net/state/cadata"
)

func TestAddPrefix(t *testing.T) {
t.Parallel()
ctx := testutil.Context(t)
s := cadata.NewMem(cadata.DefaultHash, 1<<16)
s := stores.NewMem()
ag := NewMachine(1<<13, 1<<16)
b := ag.NewBuilder(s)

Expand Down
8 changes: 4 additions & 4 deletions src/gotkv/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (a *Machine) MaxSize() int {

// GetF calls fn with the value corresponding to key in the instance x.
// The value must not be used outside the callback.
func (a *Machine) GetF(ctx context.Context, s cadata.Getter, x Root, key []byte, fn func([]byte) error) error {
func (a *Machine) GetF(ctx context.Context, s stores.Reading, x Root, key []byte, fn func([]byte) error) error {
it := a.NewIterator(s, x, kvstreams.SingleItemSpan(key))
var ent Entry
err := it.Next(ctx, &ent)
Expand All @@ -119,7 +119,7 @@ func (a *Machine) GetF(ctx context.Context, s cadata.Getter, x Root, key []byte,
}

// Get returns the value corresponding to key in the instance x.
func (a *Machine) Get(ctx context.Context, s cadata.Getter, x Root, key []byte) ([]byte, error) {
func (a *Machine) Get(ctx context.Context, s stores.Reading, x Root, key []byte) ([]byte, error) {
var ret []byte
if err := a.GetF(ctx, s, x, key, func(data []byte) error {
ret = append([]byte{}, data...)
Expand Down Expand Up @@ -159,7 +159,7 @@ func (a *Machine) NewEmpty(ctx context.Context, s stores.RW) (*Root, error) {
}

// MaxEntry returns the entry in the instance x, within span, with the greatest lexicographic value.
func (a *Machine) MaxEntry(ctx context.Context, s cadata.Getter, x Root, span Span) (*Entry, error) {
func (a *Machine) MaxEntry(ctx context.Context, s stores.Reading, x Root, span Span) (*Entry, error) {
rp := ptree.ReadParams[Entry, Ref]{
Store: &ptreeGetter{ag: a.da, s: s},
Compare: compareEntries,
Expand Down Expand Up @@ -231,7 +231,7 @@ func (a *Machine) NewBuilder(s stores.RW) *Builder {

// NewIterator returns an iterator for the instance rooted at x, which
// will emit all keys within span in the instance.
func (a *Machine) NewIterator(s Getter, root Root, span Span) *Iterator {
func (a *Machine) NewIterator(s stores.Reading, root Root, span Span) *Iterator {
if span.End != nil && bytes.Compare(span.Begin, span.End) > 0 {
panic(fmt.Sprintf("cannot iterate over descending span. begin=%q end=%q", span.Begin, span.End))
}
Expand Down
Loading