You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: backup.go
    path of file: ./repos/lotus/cmd/lotus
    
    the code of the file until where you have to start completion: package main

import (
	"os"

	dstore "github.com/ipfs/go-datastore"
	"github.com/mitchellh/go-homedir"
	"github.com/urfave/cli/v2"
	"golang.org/x/xerrors"
	"gopkg.in/cheggaaa/pb.v1"

	"github.com/filecoin-project/go-jsonrpc"

	"github.com/filecoin-project/lotus/chain/store"
	lcli "github.com/filecoin-project/lotus/cli"
	"github.com/filecoin-project/lotus/lib/backupds"
	"github.com/filecoin-project/lotus/node/config"
	"github.com/filecoin-project/lotus/node/repo"
)

var backupCmd = lcli.BackupCmd("repo", repo.FullNode, func(cctx *cli.Context) (lcli.BackupAPI, jsonrpc.ClientCloser, error) {
	return lcli.GetFullNodeAPI(cctx)
})

func restore(cctx *cli.Context, r repo.Repo) error {
	bf, err := homedir.Expand(cctx.Path("restore"))
	if err != nil {
		return xerrors.Errorf("expand backup file path: %w", err)
	}

	st, err := os.Stat(bf)
	if err != nil {
		return xerrors.Errorf("stat backup file (%s): %w", bf, err)
	}

	f, err := os.Open(bf)
	if err != nil {
		return xerrors.Errorf("opening backup file: %w", err)
	}
	defer f.Close() // nolint:errcheck

	lr, err := r.Lock(repo.FullNode)
	if err != nil {
		return err
	}
	defer lr.Close() // nolint:errcheck

	if cctx.IsSet("restore-config") {
		log.Info("Restoring config")

		cf, err := homedir.Expand(cctx.String("restore-config"))
		if err != nil {
			return xerrors.Errorf("expanding config path: %w", 
    
func restore(cctx *cli.Context, r repo.Repo) error {
	bf, err := homedir.Expand(cctx.Path("restore"))
	if err != nil {
		return xerrors.Errorf("expand backup file path: %w", err)
	}

	st, err := os.Stat(bf)
	if err != nil {
		return xerrors.Errorf("stat backup file (%s): %w", bf, err)
	}

	f, err := os.Open(bf)
	if err != nil {
		return xerrors.Errorf("opening backup file: %w", err)
	}
	defer f.Close() // nolint:errcheck

	lr, err := r.Lock(repo.FullNode)
	if err != nil {
		return err
	}
	defer lr.Close() // nolint:errcheck

	if cctx.IsSet("restore-config") {
		log.Info("Restoring config")

		cf, err := homedir.Expand(cctx.String("restore-config"))
		if err != nil {
			return xerrors.Errorf("expanding config path: %w", err)
		}

		_, err = os.Stat(cf)
		if err != nil {
			return xerrors.Errorf("stat config file (%s): %w", cf, err)
		}

		var cerr error
		err = lr.SetConfig(func(raw interface{}) {
			rcfg, ok := raw.(*config.FullNode)
			if !ok {
				cerr = xerrors.New("expected miner config")
				return
			}

			ff, err := config.FromFile(cf, config.SetDefault(func() (interface{}, error) { return rcfg, nil }))
			if err != nil {
				cerr = xerrors.Errorf("loading config: %w", err)
				return
			}

			*rcfg = *ff.(*config.FullNode)
		})
		if cerr != nil {
			return cerr
		}
		if err != nil {
			return xerrors.Errorf("setting config: %w", err)
		}

	} else {
		log.Warn("--restore-config NOT SET, WILL USE DEFAULT VALUES")
	}

	log.Info("Restoring metadata backup")

	mds, err := lr.Datastore(cctx.Context, "/metadata")
	if err != nil {
		return err
	}

	bar := pb.New64(st.Size())
	br := bar.NewProxyReader(f)
	bar.ShowTimeLeft = true
	bar.ShowPercent = true
	bar.ShowSpeed = true
	bar.Units = pb.U_BYTES

	bar.Start()
	err = backupds.RestoreInto(br, mds)
	bar.Finish()

	if err != nil {
		return xerrors.Errorf("restoring metadata: %w", err)
	}

	log.Info("Resetting chainstore metadata")

	chainHead := dstore.NewKey("head")
	if err := mds.Delete(cctx.Context, chainHead); err != nil {
		return xerrors.Errorf("clearing chain head: %w", err)
	}
	if err := store.FlushValidationCache(cctx.Context, mds); err != nil {
		return xerrors.Errorf("clearing chain validation cache: %w", err)
	}

	return nil
}