veyron/services/store: Objects can no longer be accessed by id.

Objects can no longer be accessed via the path "/uid/<id>".
"/uid" is not a special name, and can be used as the store
admin pleases.

Change-Id: I28aef1f788e98586b97b23955942ccd4d8e99a02
diff --git a/runtimes/google/vsync/watcher_test.go b/runtimes/google/vsync/watcher_test.go
index b9d8a79..7804409 100644
--- a/runtimes/google/vsync/watcher_test.go
+++ b/runtimes/google/vsync/watcher_test.go
@@ -149,7 +149,7 @@
 	batch.Changes = []watch.Change{
 		// 1st transaction: create "/" and "/a" and "/a/b" as 3 new objects (prior versions are 0).
 		watch.Change{
-			Name:  "/uid/4c6db51aa740d8c62b90df874503e285",
+			Name:  "",
 			State: 0,
 			Value: &raw.Mutation{
 				ID: storage.ID{0x4c, 0x6d, 0xb5, 0x1a, 0xa7, 0x40, 0xd8, 0xc6,
@@ -170,7 +170,7 @@
 			Continued:    true,
 		},
 		watch.Change{
-			Name:  "/uid/082bc42e15af4fcf611d7f19a8d7831f",
+			Name:  "",
 			State: 0,
 			Value: &raw.Mutation{
 				ID: storage.ID{0x8, 0x2b, 0xc4, 0x2e, 0x15, 0xaf, 0x4f, 0xcf,
@@ -191,7 +191,7 @@
 			Continued:    true,
 		},
 		watch.Change{
-			Name:  "/uid/6e4a327c297d76fb5142b1b1d95b2d07",
+			Name:  "",
 			State: 0,
 			Value: &raw.Mutation{
 				ID: storage.ID{0x6e, 0x4a, 0x32, 0x7c, 0x29, 0x7d, 0x76, 0xfb,
@@ -208,7 +208,7 @@
 
 		// 2nd transaction: create "/a/c" as a new object, which also updates "a" (its "Dir" field).
 		watch.Change{
-			Name:  "/uid/082bc42e15af4fcf611d7f19a8d7831f",
+			Name:  "",
 			State: 0,
 			Value: &raw.Mutation{
 				ID: storage.ID{0x8, 0x2b, 0xc4, 0x2e, 0x15, 0xaf, 0x4f, 0xcf,
@@ -234,7 +234,7 @@
 			Continued:    true,
 		},
 		watch.Change{
-			Name:  "/uid/70ff65ec0f825f44b69f895eea759d71",
+			Name:  "",
 			State: 0,
 			Value: &raw.Mutation{
 				ID: storage.ID{0x70, 0xff, 0x65, 0xec, 0xf, 0x82, 0x5f, 0x44,
diff --git a/services/store/memstore/blackbox/graph_test.go b/services/store/memstore/blackbox/graph_test.go
index 6f2770e..6afbb4b 100644
--- a/services/store/memstore/blackbox/graph_test.go
+++ b/services/store/memstore/blackbox/graph_test.go
@@ -1,7 +1,6 @@
 package blackbox
 
 import (
-	"fmt"
 	"testing"
 
 	_ "veyron/lib/testutil"
@@ -54,8 +53,10 @@
 
 	// Verify that all the nodes still exist.
 	st.GC()
-	for _, id := range ids {
-		ExpectExists(t, st, id)
+	for i, node := range nodes {
+		path := node.Label
+		id := ids[i]
+		ExpectExists(t, st, path, id)
 	}
 
 	// Truncate the graph to length 3.
@@ -68,11 +69,13 @@
 	}
 
 	st.GC()
-	for i, id := range ids {
+	for i, node := range nodes {
+		path := node.Label
+		id := ids[i]
 		if i < 3 {
-			ExpectExists(t, st, id)
+			ExpectExists(t, st, path, id)
 		} else {
-			ExpectNotExists(t, st, id)
+			ExpectNotExists(t, st, path, id)
 		}
 	}
 }
@@ -97,17 +100,18 @@
 	}
 	id := stat.ID
 
-	// Create a linked list using /uid/xxx names.
-	tr := memstore.NewTransaction()
+	// Create a linked list.
+	path := ""
 	var nodes [linearNodeCount]*Node
 	var ids [linearNodeCount]storage.ID
+	tr := memstore.NewTransaction()
 	for i := 0; i != linearNodeCount; i++ {
-		node := &Node{Label: fmt.Sprintf("Node[%d]", i)}
+		path = path + "/Children/a"
+		node := &Node{Label: path}
 		nodes[i] = node
-		name := fmt.Sprintf("/uid/%s/Children/a", id)
-		stat, err := st.Bind(name).Put(rootPublicID, tr, node)
+		stat, err := st.Bind(path).Put(rootPublicID, tr, node)
 		if err != nil || stat == nil {
-			t.Errorf("Unexpected error: %s: %s", name, err)
+			t.Errorf("Unexpected error: %s: %s", path, err)
 		}
 		id = stat.ID
 		ids[i] = id
@@ -116,9 +120,8 @@
 	// Add a back-loop.
 	{
 		node := nodes[linearNodeCount-1]
-		id := ids[linearNodeCount-1]
 		node.Children = map[string]storage.ID{"a": ids[loopNodeIndex]}
-		if _, err := st.Bind(fmt.Sprintf("/uid/%s", id)).Put(rootPublicID, tr, node); err != nil {
+		if _, err := st.Bind(node.Label).Put(rootPublicID, tr, node); err != nil {
 			t.Errorf("Unexpected error: %s", err)
 		}
 	}
@@ -126,26 +129,29 @@
 
 	// Verify that all the nodes still exist.
 	st.GC()
-	for _, id := range ids {
-		ExpectExists(t, st, id)
+	for i, node := range nodes {
+		path := node.Label
+		id := ids[i]
+		ExpectExists(t, st, path, id)
 	}
 
 	// Truncate part of the loop.
 	{
 		node := nodes[cutNodeIndex]
-		id := ids[cutNodeIndex]
 		node.Children = nil
-		if _, err := st.Bind(fmt.Sprintf("/uid/%s", id)).Put(rootPublicID, nil, node); err != nil {
+		if _, err := st.Bind(node.Label).Put(rootPublicID, nil, node); err != nil {
 			t.Errorf("Unexpected error: %s", err)
 		}
 	}
 
 	st.GC()
-	for i, id := range ids {
+	for i, node := range nodes {
+		path := node.Label
+		id := ids[i]
 		if i <= cutNodeIndex {
-			ExpectExists(t, st, id)
+			ExpectExists(t, st, path, id)
 		} else {
-			ExpectNotExists(t, st, id)
+			ExpectNotExists(t, st, path, id)
 		}
 	}
 }
diff --git a/services/store/memstore/blackbox/sync_integration_test.go b/services/store/memstore/blackbox/sync_integration_test.go
index 6e56574..06139f4 100644
--- a/services/store/memstore/blackbox/sync_integration_test.go
+++ b/services/store/memstore/blackbox/sync_integration_test.go
@@ -17,7 +17,7 @@
 	tr := memstore.NewTransaction()
 	id1 := Put(t, st, tr, "/", "val1")
 	id2 := Put(t, st, tr, "/a", "val2")
-	Put(t, st, tr, "/a/b", "val3")
+	id3 := Put(t, st, tr, "/a/b", "val3")
 	Commit(t, tr)
 
 	// Remove /a/b
@@ -53,9 +53,10 @@
 	PutMutations(t, target, Mutations(cb.Changes))
 	GC(t, target)
 
-	// Expect that the target contains id1 and id2
-	ExpectExists(t, target, id1)
-	ExpectExists(t, target, id2)
+	// Expect that the target contains id1 and id2 but not id3
+	ExpectExists(t, target, "/", id1)
+	ExpectExists(t, target, "/a", id2)
+	ExpectNotExists(t, target, "/a/b", id3)
 }
 
 func TestSyncTransaction(t *testing.T) {
@@ -87,9 +88,9 @@
 	GC(t, target)
 
 	// Expect that the target contains id1, id2, id3
-	ExpectExists(t, target, id1)
-	ExpectExists(t, target, id2)
-	ExpectExists(t, target, id3)
+	ExpectExists(t, target, "/", id1)
+	ExpectExists(t, target, "/a", id2)
+	ExpectExists(t, target, "/a/b", id3)
 
 	// Next transaction, remove /a/b
 	tr = memstore.NewTransaction()
@@ -106,7 +107,7 @@
 	GC(t, target)
 
 	// Expect that the target contains id1, id2, but not id3
-	ExpectExists(t, target, id1)
-	ExpectExists(t, target, id2)
-	ExpectNotExists(t, target, id3)
+	ExpectExists(t, target, "/", id1)
+	ExpectExists(t, target, "/a", id2)
+	ExpectNotExists(t, target, "/a/b", id3)
 }
diff --git a/services/store/memstore/blackbox/util.go b/services/store/memstore/blackbox/util.go
index 569c504..d432ad5 100644
--- a/services/store/memstore/blackbox/util.go
+++ b/services/store/memstore/blackbox/util.go
@@ -1,7 +1,6 @@
 package blackbox
 
 import (
-	"fmt"
 	"io/ioutil"
 	"os"
 	"runtime"
@@ -123,19 +122,22 @@
 	}
 }
 
-func ExpectExists(t *testing.T, st *memstore.Store, id storage.ID) {
-	_, err := st.Bind(fmt.Sprintf("/uid/%s", id)).Get(rootPublicID, nil)
+func ExpectExists(t *testing.T, st *memstore.Store, path string, id storage.ID) {
+	_, file, line, _ := runtime.Caller(1)
+	e, err := st.Bind(path).Get(rootPublicID, nil)
 	if err != nil {
-		_, file, line, _ := runtime.Caller(1)
 		t.Errorf("%s(%d): Expected value for ID: %x", file, line, id)
 	}
+	if e.Stat.ID != id {
+		t.Errorf("%s(%d): expected id to be %v, but was %v", file, line, id, e.Stat.ID)
+	}
 }
 
-func ExpectNotExists(t *testing.T, st *memstore.Store, id storage.ID) {
-	x, err := st.Bind(fmt.Sprintf("/uid/%s", id)).Get(rootPublicID, nil)
+func ExpectNotExists(t *testing.T, st *memstore.Store, path string, id storage.ID) {
+	_, file, line, _ := runtime.Caller(1)
+	e, err := st.Bind(path).Get(rootPublicID, nil)
 	if err == nil {
-		_, file, line, _ := runtime.Caller(1)
-		t.Errorf("%s(%d): Unexpected value: %v", file, line, x)
+		t.Errorf("%s(%d): Unexpected value: %v", file, line, e)
 	}
 }
 
diff --git a/services/store/memstore/state/mutable_snapshot.go b/services/store/memstore/state/mutable_snapshot.go
index c5a8b11..0845fcd 100644
--- a/services/store/memstore/state/mutable_snapshot.go
+++ b/services/store/memstore/state/mutable_snapshot.go
@@ -105,7 +105,6 @@
 var (
 	errBadPath              = verror.BadArgf("malformed path")
 	errBadRef               = verror.BadArgf("value has dangling references")
-	errCantUnlinkByID       = verror.BadArgf("can't unlink entries by ID")
 	errDuplicatePutMutation = verror.BadArgf("duplicate calls to PutMutation for the same ID")
 	errNotFound             = verror.NotFoundf("not found")
 	errNotTagList           = verror.BadArgf("not a TagList")
@@ -322,27 +321,6 @@
 	return &cp, nil
 }
 
-// resolveCell performs a path-based lookup, traversing the state from the
-// root.
-//
-// Returns (cell, suffix, v), where cell contains the value, suffix is the path
-// to the value, v is the value itself.  If the operation failed, the returned
-// cell is nil.
-func (sn *MutableSnapshot) resolveCell(checker *acl.Checker, path storage.PathName, mu *Mutations) (*Cell, storage.PathName, interface{}) {
-	// Get the starting object.
-	id, suffix, ok := path.GetID()
-	if ok {
-		path = suffix
-		// Remove garbage so that only valid uids are visible.
-		sn.gc()
-		checker.Update(uidTagList)
-	} else {
-		id = sn.rootID
-	}
-
-	return sn.resolve(checker, id, path, mu)
-}
-
 // Get returns the value for a path.
 func (sn *MutableSnapshot) Get(pid security.PublicID, path storage.PathName) (*storage.Entry, error) {
 	checker := sn.newPermChecker(pid)
@@ -376,9 +354,6 @@
 	if path.IsRoot() {
 		return sn.putRoot(checker, v)
 	}
-	if id, suffix, ok := path.GetID(); ok && len(suffix) == 0 {
-		return sn.putValueByID(checker, id, v)
-	}
 	return sn.putValue(checker, path, v)
 }
 
@@ -535,17 +510,6 @@
 	return ncell, nil
 }
 
-// putValueByID replaces a value referred to by ID.
-func (sn *MutableSnapshot) putValueByID(checker *acl.Checker, id storage.ID, v interface{}) (*Cell, error) {
-	checker.Update(uidTagList)
-	if !checker.IsAllowed(security.WriteLabel) {
-		return nil, errPermissionDenied
-	}
-
-	sn.gc()
-	return sn.add(checker, id, v)
-}
-
 // Remove removes a value.
 func (sn *MutableSnapshot) Remove(pid security.PublicID, path storage.PathName) error {
 	checker := sn.newPermChecker(pid)
@@ -559,9 +523,6 @@
 		sn.mutations.SetRootID = true
 		return nil
 	}
-	if path.IsStrictID() {
-		return errCantUnlinkByID
-	}
 
 	// Split the names into directory and field parts.
 	cell, suffix, _ := sn.resolveCell(checker, path[:len(path)-1], sn.mutations)
diff --git a/services/store/memstore/state/mutable_snapshot_test.go b/services/store/memstore/state/mutable_snapshot_test.go
index 1930ff1..c65794c 100644
--- a/services/store/memstore/state/mutable_snapshot_test.go
+++ b/services/store/memstore/state/mutable_snapshot_test.go
@@ -1,7 +1,6 @@
 package state
 
 import (
-	"fmt"
 	"runtime"
 	"testing"
 
@@ -48,13 +47,17 @@
 	return stat.ID, dir
 }
 
-func expectExists(t *testing.T, sn *MutableSnapshot, id storage.ID) {
+func expectExists(t *testing.T, sn *MutableSnapshot, path string, id storage.ID) {
 	_, file, line, _ := runtime.Caller(1)
 	if !sn.idTable.Contains(&Cell{ID: id}) {
 		t.Errorf("%s(%d): does not exist: %s", file, line, id)
 	}
-	if _, err := sn.Get(rootPublicID, storage.ParsePath(fmt.Sprintf("/uid/%s", id))); err != nil {
-		t.Errorf("%s(%d): does not exist: %s", file, line, id)
+	e, err := sn.Get(rootPublicID, storage.ParsePath(path))
+	if err != nil {
+		t.Errorf("%s(%d): does not exist: %s", file, line, path)
+	}
+	if e.Stat.ID != id {
+		t.Errorf("%s(%d): expected id to be %v, but was %v", file, line, id, e.Stat.ID)
 	}
 }
 
@@ -158,11 +161,11 @@
 	id3, d3 := mkdir(t, sn, "/Entries/a/Entries/b")
 	id4, d4 := mkdir(t, sn, "/Entries/a/Entries/b/Entries/c")
 	id5, d5 := mkdir(t, sn, "/Entries/a/Entries/b/Entries/d")
-	expectExists(t, sn, id1)
-	expectExists(t, sn, id2)
-	expectExists(t, sn, id3)
-	expectExists(t, sn, id4)
-	expectExists(t, sn, id5)
+	expectExists(t, sn, "/", id1)
+	expectExists(t, sn, "/Entries/a", id2)
+	expectExists(t, sn, "/Entries/a/Entries/b", id3)
+	expectExists(t, sn, "/Entries/a/Entries/b/Entries/c", id4)
+	expectExists(t, sn, "/Entries/a/Entries/b/Entries/d", id5)
 
 	// Parent directory has to exist.
 	d := &Dir{}
@@ -182,8 +185,8 @@
 		t.Errorf("Unexpected error: %s", err)
 	}
 	sn.gc()
-	expectExists(t, sn, id1)
-	expectExists(t, sn, id2)
+	expectExists(t, sn, "/", id1)
+	expectExists(t, sn, "/Entries/a", id2)
 	expectNotExists(t, sn, id3)
 	expectNotExists(t, sn, id4)
 	expectNotExists(t, sn, id5)
@@ -209,7 +212,7 @@
 	if err != nil {
 		t.Errorf("Unexpected error: %s", err)
 	}
-	expectExists(t, sn, stat.ID)
+	expectExists(t, sn, "/Entries/a", stat.ID)
 	checkInRefs(t, sn)
 
 	// Change the ref to refer to itself.
@@ -218,7 +221,7 @@
 		t.Errorf("Unexpected error: %s", err)
 	}
 	sn.gc()
-	expectExists(t, sn, stat.ID)
+	expectExists(t, sn, "/Entries/a", stat.ID)
 	checkInRefs(t, sn)
 
 	// Remove it.
@@ -239,11 +242,11 @@
 	id3, d3 := mkdir(t, sn, "/a/b")
 	id4, d4 := mkdir(t, sn, "/a/b/c")
 	id5, d5 := mkdir(t, sn, "/a/b/c/d")
-	expectExists(t, sn, id1)
-	expectExists(t, sn, id2)
-	expectExists(t, sn, id3)
-	expectExists(t, sn, id4)
-	expectExists(t, sn, id5)
+	expectExists(t, sn, "/", id1)
+	expectExists(t, sn, "/a", id2)
+	expectExists(t, sn, "/a/b", id3)
+	expectExists(t, sn, "/a/b/c", id4)
+	expectExists(t, sn, "/a/b/c/d", id5)
 	checkInRefs(t, sn)
 
 	// Parent directory has to exisn.
@@ -264,8 +267,8 @@
 		t.Errorf("Unexpected error: %s", err)
 	}
 	sn.gc()
-	expectExists(t, sn, id1)
-	expectExists(t, sn, id2)
+	expectExists(t, sn, "/", id1)
+	expectExists(t, sn, "/a", id2)
 	expectNotExists(t, sn, id3)
 	expectNotExists(t, sn, id4)
 	expectNotExists(t, sn, id5)
diff --git a/services/store/memstore/state/snapshot.go b/services/store/memstore/state/snapshot.go
index 4213a55..9c352f5 100644
--- a/services/store/memstore/state/snapshot.go
+++ b/services/store/memstore/state/snapshot.go
@@ -106,27 +106,13 @@
 	return e, nil
 }
 
-// resolveCell performs a path-based lookup, traversing the state from the
-// root.
+// resolveCell performs a path-based lookup, traversing the state from the root.
 //
 // Returns (cell, suffix, v), where cell contains the value, suffix is the path
 // to the value, v is the value itself.  If the operation failed, the returned
 // cell is nil.
 func (sn *snapshot) resolveCell(checker *acl.Checker, path storage.PathName, mu *Mutations) (*Cell, storage.PathName, interface{}) {
-	// Get the starting object.
-	id, suffix, ok := path.GetID()
-	if ok {
-		path = suffix
-		checker.Update(uidTagList)
-	} else {
-		id = sn.rootID
-	}
-
-	return sn.resolve(checker, id, path, mu)
-}
-
-func (sn *snapshot) resolve(checker *acl.Checker, id storage.ID, path storage.PathName, mu *Mutations) (*Cell, storage.PathName, interface{}) {
-	cell := sn.Find(id)
+	cell := sn.Find(sn.rootID)
 	if cell == nil {
 		return nil, nil, nil
 	}
diff --git a/services/store/memstore/watch/raw_processor.go b/services/store/memstore/watch/raw_processor.go
index 5c8d76e..68dc10a 100644
--- a/services/store/memstore/watch/raw_processor.go
+++ b/services/store/memstore/watch/raw_processor.go
@@ -1,8 +1,6 @@
 package watch
 
 import (
-	"fmt"
-
 	"veyron/services/store/memstore/refs"
 	"veyron/services/store/memstore/state"
 	"veyron/services/store/raw"
@@ -89,7 +87,6 @@
 			Dir:          flattenDir(refs.FlattenDir(cell.Dir)),
 		}
 		change := watch.Change{
-			Name:  uidName(id),
 			State: watch.Exists,
 			Value: value,
 		}
@@ -125,7 +122,6 @@
 			}
 			// TODO(tilaks): don't clone value.
 			change := watch.Change{
-				Name:  uidName(p.rootID),
 				State: watch.DoesNotExist,
 				Value: value,
 			}
@@ -157,7 +153,6 @@
 		}
 		// TODO(tilaks): don't clone value.
 		change := watch.Change{
-			Name:  uidName(id),
 			State: watch.Exists,
 			Value: value,
 		}
@@ -180,7 +175,6 @@
 		}
 		// TODO(tilaks): don't clone value.
 		change := watch.Change{
-			Name:  uidName(id),
 			State: watch.DoesNotExist,
 			Value: value,
 		}
@@ -190,11 +184,6 @@
 	return changes, nil
 }
 
-// uidName returns path "<uid dir name>/<id>" for the object.
-func uidName(id storage.ID) string {
-	return fmt.Sprintf("/%s/%s", storage.UIDDirName, id)
-}
-
 // TODO(tilaks): revisit when raw.Mutation.Dir is of type []*storage.DEntry
 // (once we support optional structs in the idl).
 func flattenDir(pdir []*storage.DEntry) []storage.DEntry {