diff --git a/application/authentication_test.go b/application/authentication_test.go index 2980de2..008a520 100644 --- a/application/authentication_test.go +++ b/application/authentication_test.go @@ -55,7 +55,7 @@ func TestAuthenticationSelectsCallerRootAndVerifiesBeforeReturning(t *testing.T) t.Fatal(err) } value := []byte("a/b") - state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, Entries: []engine.Entry{{Label: value, Target: cid.MustParse("bafkqaaa")}}} + state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, Entries: []engine.Entry{{Label: value, Target: cid.MustParse("bafkqaaa")}}} candidate, err := app.Store(t.Context(), state, cid.Undef) if err != nil { t.Fatal(err) diff --git a/application/backup/plan_backup.go b/application/backup/plan_backup.go index 268142c..1d203ab 100644 --- a/application/backup/plan_backup.go +++ b/application/backup/plan_backup.go @@ -110,7 +110,7 @@ func (s *PlanService) Backup(ctx context.Context, message string) (backupResult backend := maltcid.BackendKindUnknown if baseCID.Defined() { descriptor, _, parseErr := maltcid.ParseRoot(baseCID) - if parseErr != nil || descriptor.Layout != maltcid.Prefix || descriptor.DerivationProfile != uint8(derivation.SHA256) { + if parseErr != nil || descriptor.Layout != maltcid.Map || descriptor.DerivationProfile != uint8(derivation.SHA256) { return nil, fmt.Errorf("backup plan base is not a supported Prefix Root with byte-label inputs") } profile, profileErr := maltcid.Profile(descriptor.Profile) diff --git a/application/backup/plan_service_test.go b/application/backup/plan_service_test.go index 9481b6d..53a4a81 100644 --- a/application/backup/plan_service_test.go +++ b/application/backup/plan_service_test.go @@ -150,7 +150,7 @@ type inspectingPlanFilesystem struct { } func newInspectingPlanFilesystem(order *[]string) *inspectingPlanFilesystem { - root, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, make([]byte, maltcid.KZGCommitmentSize)) + root, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, make([]byte, maltcid.KZGCommitmentSize)) if err != nil { panic(err) } @@ -669,7 +669,7 @@ func TestPlanBackupRetryRestoresExactDurableCandidateBeforeRemoteWork(t *testing } workspace := bucketsyncWorkspaceInitialized(t) base := cid.MustParse(workspace.Base.Root) - candidate, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, append([]byte{1}, make([]byte, maltcid.KZGCommitmentSize-1)...)) + candidate, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, append([]byte{1}, make([]byte, maltcid.KZGCommitmentSize-1)...)) if err != nil { t.Fatal(err) } @@ -751,7 +751,7 @@ func TestPlanBackupRejectsConflictAndUnacceptedBaseBeforeSnapshotPublication(t * policy: func(t *testing.T, _ bucketsync.Workspace) PlanRootPolicy { commitment := make([]byte, maltcid.KZGCommitmentSize) commitment[0] = 1 - root, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, commitment) + root, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, commitment) if err != nil { t.Fatal(err) } @@ -987,7 +987,7 @@ func TestRestoredBaselinePreventsUnchangedRepublish(t *testing.T) { func bucketsyncWorkspaceInitialized(t *testing.T) bucketsync.Workspace { t.Helper() - root, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, make([]byte, maltcid.KZGCommitmentSize)) + root, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, make([]byte, maltcid.KZGCommitmentSize)) if err != nil { t.Fatal(err) } diff --git a/application/writeback/service_test.go b/application/writeback/service_test.go index 1510686..99e4394 100644 --- a/application/writeback/service_test.go +++ b/application/writeback/service_test.go @@ -242,7 +242,7 @@ func newWritebackFixture(t *testing.T) *writebackFixture { oldPayload := writebackRawCID(t, []byte("old")) newBody := []byte("new") newPayload := writebackRawCID(t, newBody) - state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, Entries: []engine.Entry{{Label: []byte("payload"), Target: oldPayload}}} + state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, Entries: []engine.Entry{{Label: []byte("payload"), Target: oldPayload}}} base, err := authentication.Prepare(t.Context(), e, state) if err != nil { t.Fatal(err) diff --git a/cmd/malt/content_trust_test.go b/cmd/malt/content_trust_test.go index 9581a6c..c7cceff 100644 --- a/cmd/malt/content_trust_test.go +++ b/cmd/malt/content_trust_test.go @@ -46,7 +46,7 @@ func TestExplicitCIDContentCommandsDoNotOpenBrokenTrustStore(t *testing.T) { catCmd.SetContext(t.Context()) rmCmd.SetContext(t.Context()) - selected, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, make([]byte, 48)) + selected, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, make([]byte, 48)) if err != nil { t.Fatal(err) } diff --git a/cmd/malt/verify_test.go b/cmd/malt/verify_test.go index b265f10..6816202 100644 --- a/cmd/malt/verify_test.go +++ b/cmd/malt/verify_test.go @@ -29,7 +29,7 @@ func TestVerifyCommandBindsTypedResultToSelectedRequest(t *testing.T) { } e := engine.New(profiles) nodes := memory.NewNodes() - root, err := e.Build(t.Context(), engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, Entries: []engine.Entry{{Label: []byte("docs/file"), Target: cid.MustParse("bafkqaaa")}}}, nodes) + root, err := e.Build(t.Context(), engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, Entries: []engine.Entry{{Label: []byte("docs/file"), Target: cid.MustParse("bafkqaaa")}}}, nodes) if err != nil { t.Fatal(err) } diff --git a/docs/runtime-migration.md b/docs/runtime-migration.md index 789bcd0..e0da773 100644 --- a/docs/runtime-migration.md +++ b/docs/runtime-migration.md @@ -23,7 +23,7 @@ not a current build contract. The original plan is available in The runtime's Go module namespace remains `github.com/dewebprotocol/malt-client` until its separately governed module migration. The module pins published Core -`v0.0.11-rc.2` by its exact release version and module checksums. This dependency +`v0.0.11-rc.4` by its exact release version and module checksums. This dependency update does not publish a runtime release or change frozen evaluator baselines. ## Preserved behavior diff --git a/docs/typed-authentication-migration.md b/docs/typed-authentication-migration.md index 051bc66..2cf8543 100644 --- a/docs/typed-authentication-migration.md +++ b/docs/typed-authentication-migration.md @@ -56,8 +56,8 @@ new versioned measurement fields. Source workspace validation is not release publication. The runtime module namespace/tag gate and exact downstream release pins remain separate from this source migration. -Native builds pin published Core `v0.0.11-rc.2`, commit -`a8b0f9260ff025e834a803f87161685914604d11`, for independent module builds. This source +Native builds pin published Core `v0.0.11-rc.4`, commit +`595f1e05aa86b0339addaa0f0e2ac6672faa8e00`, for independent module builds. This source integration is not a runtime or browser release. Prefix layout 4 authenticates original label bytes and targets. Coordinates route the tree lookup; distinct labels at the same full coordinate return an @@ -66,3 +66,9 @@ conversion path. Existing Prefix trees must be rebuilt from their original labels and targets, including parent roots that reference rebuilt children. New roots use the remote's advertised backend as an untrusted creation hint; updates preserve the existing Root descriptor. + +Core rc.4 names the authentication layouts Map (4) and List (3). It includes +rc.3's empty-cell scalar-zero encoding: roots and proofs built with rc.2 or +earlier must be regenerated from original inputs, including parents that refer +to changed children. There is no compatibility reader or automatic migration. +Runtime application layout names and Root V=0 remain unchanged. diff --git a/filesystem/service/service_test.go b/filesystem/service/service_test.go index 4557f5f..940c9d8 100644 --- a/filesystem/service/service_test.go +++ b/filesystem/service/service_test.go @@ -289,7 +289,7 @@ func TestSelectedRootMismatchAndClosedHandleFailClosed(t *testing.T) { func testView(t *testing.T) View { t.Helper() root, err := maltcid.NewRoot(maltcid.RootDescriptor{ - Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256, + Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256, }, make([]byte, maltcid.IPACommitmentSize)) if err != nil { t.Fatal(err) @@ -423,7 +423,7 @@ func authenticatedFileResolution(t *testing.T, view *View, path string, payload } e := engine.New(profiles) nodes := memory.NewNodes() - root, err := e.Build(t.Context(), engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, Entries: []engine.Entry{{Label: []byte(path), Target: payload}}}, nodes) + root, err := e.Build(t.Context(), engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, Entries: []engine.Entry{{Label: []byte(path), Target: payload}}}, nodes) if err != nil { t.Fatal(err) } diff --git a/go.mod b/go.mod index 6c1139e..efcc677 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.26.8 require ( github.com/Microsoft/go-winio v0.6.2 github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf - github.com/dewebprotocol/malt-core v0.0.11-rc.2 + github.com/dewebprotocol/malt-core v0.0.11-rc.4 github.com/hanwen/go-fuse/v2 v2.11.0 github.com/ipfs/boxo v0.41.0 github.com/ipfs/go-block-format v0.2.4 diff --git a/go.sum b/go.sum index b5cbeed..60bfe9e 100644 --- a/go.sum +++ b/go.sum @@ -23,8 +23,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 h1:5RVFMOWjMyRy8cARdy79nAmgYw3hK/4HUq48LQ6Wwqo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= -github.com/dewebprotocol/malt-core v0.0.11-rc.2 h1:n1znvAKDKeH+vlrZ7o1nvinro2CGb1LoBtf0O3WOPzQ= -github.com/dewebprotocol/malt-core v0.0.11-rc.2/go.mod h1:uAbiKECccmR8MlDotFWLdAgp+JFStdSn2SqA6ILEXhA= +github.com/dewebprotocol/malt-core v0.0.11-rc.4 h1:txnIBdjlVnQkPMUs6xxNwIEOoZxpQdJbmPDXkZbzgvM= +github.com/dewebprotocol/malt-core v0.0.11-rc.4/go.mod h1:uAbiKECccmR8MlDotFWLdAgp+JFStdSn2SqA6ILEXhA= github.com/filecoin-project/go-clock v0.1.0 h1:SFbYIM75M8NnFm1yMHhN9Ahy3W5bEZV9gd6MPfXbKVU= github.com/filecoin-project/go-clock v0.1.0/go.mod h1:4uB/O4PvOjlx1VCMdZ9MyDZXRm//gkj1ELEbxfI1AZs= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= diff --git a/internal/runtime/writeback.go b/internal/runtime/writeback.go index 0f1cf9c..ef9d0ea 100644 --- a/internal/runtime/writeback.go +++ b/internal/runtime/writeback.go @@ -115,7 +115,7 @@ func newGatewayWritableBinding(ctx context.Context, opts gatewayWritableBindingO return nil, fmt.Errorf("Gateway writable binding Spec and View do not match") } descriptor, _, err := maltcid.ParseRoot(opts.View.Root) - if err != nil || descriptor.Layout != maltcid.Prefix { + if err != nil || descriptor.Layout != maltcid.Map { return nil, fmt.Errorf("Gateway writable binding requires an authenticated Prefix Root") } if nilInterface(opts.Base) || nilInterface(opts.Remote) || nilInterface(opts.Roots) || nilInterface(opts.WriterFactory) { @@ -440,7 +440,7 @@ func validCandidateRoot(base, candidate cid.Cid) bool { return false } next, _, err := maltcid.ParseRoot(candidate) - if err != nil || next.Layout != maltcid.Prefix { + if err != nil || next.Layout != maltcid.Map { return false } old, _, err := maltcid.ParseRoot(base) diff --git a/internal/runtime/writeback_test.go b/internal/runtime/writeback_test.go index 4eabd1e..b965091 100644 --- a/internal/runtime/writeback_test.go +++ b/internal/runtime/writeback_test.go @@ -628,7 +628,7 @@ func runtimeMALTMapRoot(t *testing.T, backend maltcid.BackendKind, marker byte) if backend == maltcid.BackendKindIPA { profile = maltcid.IPA256 } - root, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: profile}, commitment) + root, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: profile}, commitment) if err != nil { t.Fatal(err) } diff --git a/nodeapi/nodetest/authentication.go b/nodeapi/nodetest/authentication.go index dce4ab9..50c6707 100644 --- a/nodeapi/nodetest/authentication.go +++ b/nodeapi/nodetest/authentication.go @@ -42,7 +42,7 @@ func RunAuthentication(t *testing.T, factory AuthenticationFactory) { prepare := func(t *testing.T, label string) protocol.AuthenticationCandidate { t.Helper() state := engine.State{Descriptor: maltcid.RootDescriptor{ - Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256, + Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256, }, Entries: []engine.Entry{{Label: []byte(label), Target: cid.MustParse("bafkqaaa")}}} candidate, err := sdk.Prepare(t.Context(), e, state) if err != nil { @@ -122,7 +122,7 @@ func RunAuthentication(t *testing.T, factory AuthenticationFactory) { s := factory(t) c := prepare(t, "unwritten") bad := c - bad.State.Descriptor.Layout = maltcid.Positional + bad.State.Descriptor.Layout = maltcid.List if _, err := s.MaterializeAuthentication(t.Context(), bad); err == nil { t.Fatal("accepted mismatched Root/state descriptor") } diff --git a/nodeapi/nodetest/dataset.go b/nodeapi/nodetest/dataset.go index 8a293f3..a81e197 100644 --- a/nodeapi/nodetest/dataset.go +++ b/nodeapi/nodetest/dataset.go @@ -44,7 +44,7 @@ func RunDataset(t *testing.T, factory DatasetFactory) { t.Fatal(err) } candidate, err := sdk.Prepare(t.Context(), e, engine.State{ - Descriptor: maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, + Descriptor: maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, Entries: []engine.Entry{{Label: []byte("file"), Target: target}}, }) if err != nil { diff --git a/transport/authentication_test.go b/transport/authentication_test.go index 8cbb0a4..6db33f0 100644 --- a/transport/authentication_test.go +++ b/transport/authentication_test.go @@ -16,7 +16,7 @@ import ( ) func TestAuthenticationTransportPreservesUint64AndRejectsChangedReceipt(t *testing.T) { - descriptor := maltcid.RootDescriptor{DerivationProfile: uint8(derivation.Direct), Layout: maltcid.Positional, Profile: maltcid.IPA256} + descriptor := maltcid.RootDescriptor{DerivationProfile: uint8(derivation.Direct), Layout: maltcid.List, Profile: maltcid.IPA256} root, err := maltcid.NewRoot(descriptor, make([]byte, 32)) if err != nil { t.Fatal(err) diff --git a/transport/client_test.go b/transport/client_test.go index 3f5102a..d2fa5bc 100644 --- a/transport/client_test.go +++ b/transport/client_test.go @@ -319,7 +319,7 @@ func (a *recordingAuthorizer) Authorize(request *http.Request) error { func testAuthenticationRoot(t *testing.T) cid.Cid { t.Helper() - root, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, make([]byte, 32)) + root, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, make([]byte, 32)) if err != nil { t.Fatal(err) } diff --git a/unixfs/authentication_adapter.go b/unixfs/authentication_adapter.go index b2b8e00..d5b8732 100644 --- a/unixfs/authentication_adapter.go +++ b/unixfs/authentication_adapter.go @@ -64,7 +64,7 @@ func NewAuthenticationAdapter(layout LayoutKind, remote nodeapi.AuthenticationWr } func (a *AuthenticationAdapter) UpdateStagedRoot(ctx context.Context, previous cid.Cid, bindings map[string]string) (cid.Cid, error) { rule := uint8(derivation.SHA256) - state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: rule, Profile: a.profile}, Entries: []engine.Entry{}} + state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: rule, Profile: a.profile}, Entries: []engine.Entry{}} names := make([]string, 0, len(bindings)) for name := range bindings { names = append(names, name) @@ -125,7 +125,7 @@ func (a *AuthenticationAdapter) materialize(ctx context.Context, previous cid.Ci return expected, nil } func (a *AuthenticationAdapter) CreatePositionalPayload(ctx context.Context, chunks []cid.Cid, payload cid.Cid) (cid.Cid, error) { - state := engine.State{Descriptor: maltcid.RootDescriptor{DerivationProfile: uint8(derivation.Direct), Layout: maltcid.Positional, Profile: a.profile}, PayloadCID: payload, Entries: make([]engine.Entry, len(chunks))} + state := engine.State{Descriptor: maltcid.RootDescriptor{DerivationProfile: uint8(derivation.Direct), Layout: maltcid.List, Profile: a.profile}, PayloadCID: payload, Entries: make([]engine.Entry, len(chunks))} for i, target := range chunks { state.Entries[i] = engine.Entry{Label: coordinate.EncodeIndex(uint64(i)), Target: target} } diff --git a/unixfs/chunked_file.go b/unixfs/chunked_file.go index 2ce5d94..49fc80f 100644 --- a/unixfs/chunked_file.go +++ b/unixfs/chunked_file.go @@ -53,5 +53,5 @@ func WriteChunkedFile(ctx context.Context, blocks FileBlockStore, roots nodeapi. if expected, err := nodeapi.CIDForBlock(nodeapi.Block{Data: metadata, Codec: cid.Raw}); err != nil || !expected.Equals(payload) { return cid.Undef, nodeapi.ErrCorruptedBlock } - return roots.BuildAuthentication(ctx, engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Positional, DerivationProfile: uint8(derivation.Direct), Profile: profile}, PayloadCID: payload, Entries: entries}) + return roots.BuildAuthentication(ctx, engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.List, DerivationProfile: uint8(derivation.Direct), Profile: profile}, PayloadCID: payload, Entries: entries}) } diff --git a/unixfs/encrypted/profile_test.go b/unixfs/encrypted/profile_test.go index a993fcb..8e46fb4 100644 --- a/unixfs/encrypted/profile_test.go +++ b/unixfs/encrypted/profile_test.go @@ -865,7 +865,7 @@ func (r *profileRemote) MaterializeAuthentication(ctx context.Context, candidate if err := authentication.Materialize(ctx, r.engine, candidate, r.nodes); err != nil { return cid.Undef, err } - if candidate.State.Descriptor.Layout == maltcid.Prefix { + if candidate.State.Descriptor.Layout == maltcid.Map { bindings := make(map[string]string) for _, entry := range candidate.State.Entries { label := string(entry.Label) @@ -883,11 +883,11 @@ func (g *substitutingGraph) MaterializeAuthentication(ctx context.Context, candi if err != nil { return cid.Undef, err } - if candidate.State.Descriptor.Layout == maltcid.Prefix && g.substituteMap { + if candidate.State.Descriptor.Layout == maltcid.Map && g.substituteMap { g.substituteMap = false return cid.MustParse("bafkqaaa"), nil } - if candidate.State.Descriptor.Layout == maltcid.Positional && g.substituteList { + if candidate.State.Descriptor.Layout == maltcid.List && g.substituteList { g.substituteList = false return cid.MustParse("bafkqaaa"), nil } diff --git a/unixfs/encrypted/snapshot.go b/unixfs/encrypted/snapshot.go index 36aeb00..6a3cc30 100644 --- a/unixfs/encrypted/snapshot.go +++ b/unixfs/encrypted/snapshot.go @@ -198,7 +198,7 @@ type CandidatePublisher interface { } func (g *recordingGraph) CreateStagedRoot(ctx context.Context, bindings map[string]string) (cid.Cid, error) { - state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: g.profile}} + state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: g.profile}} names := make([]string, 0, len(bindings)) for name := range bindings { names = append(names, name) @@ -218,7 +218,7 @@ func (g *recordingGraph) CreateStagedRoot(ctx context.Context, bindings map[stri return g.record(ctx, state) } func (g *recordingGraph) CreatePositionalPayload(ctx context.Context, chunks []cid.Cid, payload cid.Cid) (cid.Cid, error) { - state := engine.State{Descriptor: maltcid.RootDescriptor{DerivationProfile: uint8(derivation.Direct), Layout: maltcid.Positional, Profile: g.profile}, PayloadCID: payload} + state := engine.State{Descriptor: maltcid.RootDescriptor{DerivationProfile: uint8(derivation.Direct), Layout: maltcid.List, Profile: g.profile}, PayloadCID: payload} for i, target := range chunks { state.Entries = append(state.Entries, engine.Entry{Label: coordinate.EncodeIndex(uint64(i)), Target: target}) } diff --git a/unixfs/model/storage.go b/unixfs/model/storage.go index 7f9e162..fb45341 100644 --- a/unixfs/model/storage.go +++ b/unixfs/model/storage.go @@ -19,9 +19,9 @@ func StorageKindFromCID(c cid.Cid) string { return "" } switch descriptor.Layout { - case maltcid.Prefix: + case maltcid.Map: return "prefix" - case maltcid.Positional: + case maltcid.List: return "positional" default: return "" diff --git a/unixfs/model/storage_format_test.go b/unixfs/model/storage_format_test.go index 4931313..7cc8c8e 100644 --- a/unixfs/model/storage_format_test.go +++ b/unixfs/model/storage_format_test.go @@ -10,11 +10,11 @@ import ( ) func TestStorageKindFromCIDUsesTypedLayout(t *testing.T) { - mapRoot, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, make([]byte, maltcid.KZGCommitmentSize)) + mapRoot, err := maltcid.NewRoot(maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}, make([]byte, maltcid.KZGCommitmentSize)) if err != nil { t.Fatal(err) } - listRoot, err := maltcid.NewRoot(maltcid.RootDescriptor{DerivationProfile: uint8(derivation.Direct), Layout: maltcid.Positional, Profile: maltcid.IPA256}, make([]byte, maltcid.IPACommitmentSize)) + listRoot, err := maltcid.NewRoot(maltcid.RootDescriptor{DerivationProfile: uint8(derivation.Direct), Layout: maltcid.List, Profile: maltcid.IPA256}, make([]byte, maltcid.IPACommitmentSize)) if err != nil { t.Fatal(err) } diff --git a/unixfs/planner/authentication.go b/unixfs/planner/authentication.go index 8de4e3c..88a92ff 100644 --- a/unixfs/planner/authentication.go +++ b/unixfs/planner/authentication.go @@ -89,7 +89,7 @@ func (p *Planner) Prepare(ctx context.Context, base cid.Cid, operations []journa if err != nil { return err } - if state.Descriptor.Layout != maltcid.Prefix || state.Descriptor.DerivationProfile != uint8(derivation.SHA256) { + if state.Descriptor.Layout != maltcid.Map || state.Descriptor.DerivationProfile != uint8(derivation.SHA256) { return fmt.Errorf("directory input rule differs from selected layout") } entries += len(state.Entries) @@ -136,7 +136,7 @@ func (p *Planner) Prepare(ctx context.Context, base cid.Cid, operations []journa child.manifest = target } else { descriptor, _, err := maltcid.ParseRoot(target) - if err != nil || descriptor.Layout != maltcid.Prefix || descriptor.DerivationProfile != uint8(derivation.SHA256) { + if err != nil || descriptor.Layout != maltcid.Map || descriptor.DerivationProfile != uint8(derivation.SHA256) { return fmt.Errorf("directory target differs from selected layout") } knownRoots[target.KeyString()] = true diff --git a/unixfs/planner/authentication_migration_test.go b/unixfs/planner/authentication_migration_test.go index 3af1963..fb26758 100644 --- a/unixfs/planner/authentication_migration_test.go +++ b/unixfs/planner/authentication_migration_test.go @@ -6,7 +6,8 @@ import ( "github.com/dewebprotocol/malt-client/unixfs" ) -// Prefix layout 4 authenticates the original labels, including @payload. +// Core rc.4 Map layout 4 authenticates original labels, including @payload, +// with the rc.3 empty-cell scalar-zero encoding. // Pin both commitment backends and application layouts. func TestPlannerPinnedProjectionRoots(t *testing.T) { vectors := []struct { @@ -14,10 +15,10 @@ func TestPlannerPinnedProjectionRoots(t *testing.T) { layout unixfs.LayoutKind base, root string }{ - {"kzg", unixfs.LayoutFlatV1, "bagcirqabaazacmfgqx4jriyby4rfnxpgy73bm3c2w55nkcxb6fnvdfz7lwjbcckv56bsefdhs4brisrzf54xdoqhzpza", "bagcirqabaazacmfjv7rzswvecxuifmazc3mlp7oe4ij5r2g4l64crjultvzh6xhgedfj6sadvdyxl26kdjgyuc2dazxa"}, - {"kzg", unixfs.LayoutHybridV1, "bagcirqabaazacmel5k7ccqru7d2tzrolfej5cftvl7bfly4vbtum5l3egotfs4bjosjidlju7geudmc6qpnsbdpnhrra", "bagcirqabaazacmfkcxqk6eoysvogmzfa3yiwpjrvezszhfbgqr5hc6db5enrqraexmbs6nxrqgaksnmnwi7ljpom7epq"}, - {"ipa", unixfs.LayoutFlatV1, "bagcirqabaaraeic53iby27mw6ofnrlkxaceafffanigphhurusbnlhl3sacen5qd5q", "bagcirqabaaraeidmrezc2pp265vm3ysai7ndv2hi7h5cspkgzb3fixohwxs7n57v2q"}, - {"ipa", unixfs.LayoutHybridV1, "bagcirqabaaraeiap4ui5j4vobybovm6o3x6fxbtpvszwczbavwcfzs23ovyorgorqq", "bagcirqabaaraeiadccijnvrda33jfrvgtiadcokb3p5ykxg66psqi7xmah24t2zhre"}, + {"kzg", unixfs.LayoutFlatV1, "bagcirqabaazacmemozf3wgitwkrh6kvwb4flz5iroaon255prynvnrjwafdoadxtpzmerwjvknndophihblh34wbn3xq", "bagcirqabaazacmffbyxr67q4zc24i3lcllbp5fhprbglxnemgjivb6ahf7qbdofkpvp2mp6f2shoxuq7j4v6kjpwgtuq"}, + {"kzg", unixfs.LayoutHybridV1, "bagcirqabaazacmeoc3zigzbk4hzs7ygbxklqhd62vpi5bk5k5fczcjneh5ditilcwxahred6nogezupmc5epa3rpqtyq", "bagcirqabaazacmfymwvjqefdokfhzwlbxrg54mn5fne5m75ta2uabursm7p5l5vje7hckcqwtzgtsyh5wz4lykwnxi4q"}, + {"ipa", unixfs.LayoutFlatV1, "bagcirqabaaraeiab3raop6y6dhq3exhxrn24wknygju7xajzn24mqqh2fp4dx7sp6e", "bagcirqabaaraeia5f64uaiw55lwf3aatoz7bwcy5hkz22gmzxjjybfj2o66flquqyy"}, + {"ipa", unixfs.LayoutHybridV1, "bagcirqabaaraeicqrq2qyui2iy3vxbhtnm3vxp2sc2vtemhfeswtbelzqzkg53ydoy", "bagcirqabaaraeibtp5tzr7jjxhwknhgoow56snrnkfp6nefmufxueem2tkugoiqom4"}, } for _, v := range vectors { t.Run(v.backend+"/"+string(v.layout), func(t *testing.T) { diff --git a/unixfs/verified_facade.go b/unixfs/verified_facade.go index ee38533..39d1d0a 100644 --- a/unixfs/verified_facade.go +++ b/unixfs/verified_facade.go @@ -640,7 +640,7 @@ func (r *verifiedReader) readStatFile(ctx context.Context, stat *Stat, offset ui func (r *verifiedReader) ReadPositionalPayloadRange(ctx context.Context, trustedPositionalRoot cid.Cid, offset, length uint64) (*ReadResult, error) { descriptor, _, parseErr := maltcid.ParseRoot(trustedPositionalRoot) - if parseErr != nil || descriptor.Layout != maltcid.Positional { + if parseErr != nil || descriptor.Layout != maltcid.List { return nil, fmt.Errorf("%w: target %s is not a positional Root", ErrNotFile, trustedPositionalRoot) } return r.readTypedRange(ctx, trustedPositionalRoot, offset, &length, nil, nil) diff --git a/unixfs/verified_facade_test.go b/unixfs/verified_facade_test.go index 2a09d5d..6757d2d 100644 --- a/unixfs/verified_facade_test.go +++ b/unixfs/verified_facade_test.go @@ -99,7 +99,7 @@ func (r *realRemote) PutWithCodec(ctx context.Context, data []byte, codec uint64 } func (r *realRemote) UpdateStagedRoot(ctx context.Context, previous cid.Cid, bindings map[string]string) (cid.Cid, error) { - state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}} + state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.KZG4096}} names := make([]string, 0, len(bindings)) for name := range bindings { names = append(names, name) diff --git a/writeplan/plan_test.go b/writeplan/plan_test.go index 3b08a33..a458f2a 100644 --- a/writeplan/plan_test.go +++ b/writeplan/plan_test.go @@ -44,7 +44,7 @@ func fixture(t *testing.T) Plan { if err := registry.Register(scheme); err != nil { t.Fatal(err) } - state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Prefix, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, Entries: []engine.Entry{{Label: []byte("name"), Target: cid.MustParse("bafkqaaa")}}} + state := engine.State{Descriptor: maltcid.RootDescriptor{Layout: maltcid.Map, DerivationProfile: uint8(derivation.SHA256), Profile: maltcid.IPA256}, Entries: []engine.Entry{{Label: []byte("name"), Target: cid.MustParse("bafkqaaa")}}} candidate, err := authentication.Prepare(t.Context(), engine.New(registry), state) if err != nil { t.Fatal(err) @@ -113,7 +113,7 @@ func TestPlanOrdersPositionalMetadataDependencies(t *testing.T) { t.Fatal(err) } parent, err := authentication.Prepare(t.Context(), engine.New(registry), engine.State{ - Descriptor: maltcid.RootDescriptor{Layout: maltcid.Positional, DerivationProfile: uint8(derivation.Direct), Profile: maltcid.IPA256}, + Descriptor: maltcid.RootDescriptor{Layout: maltcid.List, DerivationProfile: uint8(derivation.Direct), Profile: maltcid.IPA256}, PayloadCID: cid.MustParse(child.Root), }) if err != nil {