func (s *Service) DeletePin(ctx context.Context, ref swarm.Address) error {
	var iterErr error
	iterFn := func(leaf swarm.Address) error {
		err := s.pinStorage.Set(ctx, storage.ModeSetUnpin, leaf)
		if err != nil {
			iterErr = multierror.Append(err, fmt.Errorf("unable to unpin the chunk for leaf %q of root %q: %w", leaf, ref, err))
		}
		return nil
	}
	if err := s.traverser.Traverse(ctx, ref, iterFn); err != nil {
		return fmt.Errorf("traversal of %q failed: %w", ref, multierror.Append(err, iterErr))
	}
	if iterErr != nil {
		return multierror.Append(ErrTraversal, iterErr)
	}
	key := rootPinKey(ref)
	if err := s.rhStorage.Delete(key); err != nil {
		return fmt.Errorf("unable to delete pin for key %q: %w", key, err)
	}
	return nil
}
DeletePin implements Interface.DeletePin method.
package pinning
import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/ethsana/sana/pkg/storage"
	"github.com/ethsana/sana/pkg/swarm"
	"github.com/ethsana/sana/pkg/traversal"
	"github.com/hashicorp/go-multierror"
)
var ErrTraversal = errors.New("traversal iteration failed")
type Interface interface {
	CreatePin(context.Context, swarm.Address, bool) error
	DeletePin(context.Context, swarm.Address) error
	HasPin(swarm.Address) (bool, error)
	Pins() ([]swarm.Address, error)
}
const storePrefix = "root-pin"
func rootPinKey(ref swarm.Address) string {
	return fmt.Sprintf("%s-%s", storePrefix, ref)
}
func NewService(
	pinStorage storage.Storer,
	rhStorage storage.StateStorer,
	traverser traversal.Traverser,
) *Service {
	return &Service{
		pinStorage: pinStorage,
		rhStorage:  rhStorage,
		traverser:  traverser,
	}
}
type Service struct {
	pinStorage storage.Storer
	rhStorage  storage.StateStorer
	traverser  traversal.Traverser
}
func (s *Service) CreatePin(ctx context.Context, ref swarm.Address, traverse bool) error {
	iterFn := func(leaf swarm.Address) error {
		switch err := s.pinStorage.Set(ctx, storage.ModeSetPin, leaf); {
		case errors.Is(err, storage.ErrNotFound):
			ch, err := s.pinStorage.Get(ctx, storage.ModeGetRequestPin, leaf)
			if err != nil {
				return fmt.Errorf("unable to get pin for leaf %q of root %q: %w", leaf, ref, err)
			}
			_, err = s.pinStorage.Put(ctx, storage.ModePutRequestPin, ch)
			if err != nil {
				return fmt.Errorf("unable to put pin for leaf %q of root %q: %w", leaf, ref, err)
			}
		case err != nil:
			return fmt.Errorf("unable to set pin for leaf %q of root %q: %w", leaf, ref, err)
		}
		return nil
	}
	if traverse {
		if err := s.traverser.Traverse(ctx, ref, iterFn); err != nil {
			return fmt.Errorf("traversal of %q failed: %w", ref, err)
		}
	}
	key := rootPinKey(ref)
	switch err := s.rhStorage.Get(key, new(swarm.Address)); {
	case errors.Is(err, storage.ErrNotFound):
		return s.rhStorage.Put(key, ref)
	case err != nil:
		return fmt.Errorf("unable to pin %q: %w", ref, err)
	}
	return nil
}