fix for pinning same cid sharded and unsharded error

License: MIT
Signed-off-by: Wyatt Daviau <wdaviau@cs.stanford.edu>
This commit is contained in:
Wyatt Daviau 2018-04-30 12:00:22 -04:00 committed by Hector Sanjuan
parent 2bc295ca9f
commit 82facd3629
2 changed files with 28 additions and 12 deletions

View File

@ -924,6 +924,22 @@ func (c *Cluster) Pin(pin api.Pin) error {
// self-consistent. This amounts to verifying that the data structure matches
// the expected form of the pinType carried in the pin.
func (c *Cluster) validatePin(pin api.Pin, rplMin, rplMax int) error {
// In general validation requires access to the existing state.
// Multiple clusterdags may reference the same shard, sharder sessions
// update a shard pin's metadata and the same cid should not be
// tracked by different pin types
cState, err := c.consensus.State()
if err != nil && err != p2praft.ErrNoState {
return err
}
cPinExists := err != p2praft.ErrNoState && cState.Has(pin.Cid)
if cPinExists {
existing := cState.Get(pin.Cid)
if existing.Type != pin.Type {
return errors.New("cannot repin CID with different tracking method, clear state with pin rm to proceed")
}
}
switch pin.Type {
case api.DataType:
if pin.Clusterdag != nil ||
@ -934,15 +950,11 @@ func (c *Cluster) validatePin(pin api.Pin, rplMin, rplMax int) error {
if !pin.Recursive {
return errors.New("must pin shards recursively")
}
// In general multiple clusterdags may reference the same shard
// and sharder sessions typically update a shard pin's metadata.
// Hence we check for an existing shard and carefully update.
cState, err := c.consensus.State()
if err != nil && err != p2praft.ErrNoState {
return err
if pin.Clusterdag != nil {
return errors.New("shard pin should not reference cdag")
}
if err == p2praft.ErrNoState || !cState.Has(pin.Cid) {
break
if !cPinExists {
return nil
}
// State already tracks pin's CID
@ -960,7 +972,7 @@ func (c *Cluster) validatePin(pin api.Pin, rplMin, rplMax int) error {
if pin.Recursive {
return errors.New("must pin roots directly")
}
if pin.Parents.Len() > 1 {
if pin.Parents == nil || pin.Parents.Len() != 1 {
return errors.New("cdag nodes are referenced once")
}
case api.MetaType:
@ -1087,7 +1099,7 @@ func (c *Cluster) Unpin(h *cid.Cid) error {
case api.DataType:
return c.consensus.LogUnpin(pin)
case api.ShardType:
err := "unpinning shard cid %s before unpinning parent"
err := "unpinning shard CID before unpinning parent"
return errors.New(err)
case api.MetaType:
// Unpin cluster dag and referenced shards
@ -1097,7 +1109,7 @@ func (c *Cluster) Unpin(h *cid.Cid) error {
}
return c.consensus.LogUnpin(pin)
case api.CdagType:
err := "unpinning cluster dag root %s before unpinning parent"
err := "unpinning cluster dag root CID before unpinning parent"
return errors.New(err)
default:
return errors.New("unrecognized pin type")

View File

@ -26,7 +26,11 @@ test_expect_success IPFS,CLUSTER "add sharded small file to cluster" '
'
test_expect_success IPFS,CLUSTER "add same file sharded and unsharded" '
echo "complete ME"
output=`ipfs-cluster-ctl add --shard ../test_data/small_file | tail -1` &&
cid=${output:7:47} &&
test_expect_code 2 ipfs-cluster-ctl add ../test_data/small_file &&
ipfs-cluster-ctl pin rm $cid &&
ipfs-cluster-ctl add ../test_data/small_file
'