Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor blockstores #5484

Merged
merged 11 commits into from
Mar 1, 2021
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ jobs:
- run: cd extern/filecoin-ffi && make
- run:
name: "go get lotus@master"
command: cd testplans/lotus-soup && go get github.com/filecoin-project/lotus@master
command: cd testplans/lotus-soup && go mod edit -replace=github.com/filecoin-project/lotus=../..
- run:
name: "build lotus-soup testplan"
command: pushd testplans/lotus-soup && go build -tags=testground .
Expand Down
6 changes: 6 additions & 0 deletions api/api_full.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ import (

//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_full.go -package=mocks . FullNode

// ChainIO abstracts operations for accessing raw IPLD objects.
type ChainIO interface {
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
ChainHasObj(context.Context, cid.Cid) (bool, error)
}

// FullNode API is a low-level interface to the Filecoin network full node
type FullNode interface {
Common
Expand Down
68 changes: 0 additions & 68 deletions api/apibstore/apibstore.go

This file was deleted.

4 changes: 2 additions & 2 deletions api/test/paych.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
cbor "github.com/ipfs/go-ipld-cbor"

"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/blockstore"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
Expand Down Expand Up @@ -132,7 +132,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
t.Fatal("Unable to settle payment channel")
}

creatorStore := adt.WrapStore(ctx, cbor.NewCborStore(apibstore.NewAPIBlockstore(paymentCreator)))
creatorStore := adt.WrapStore(ctx, cbor.NewCborStore(blockstore.NewAPIBlockstore(paymentCreator)))

// wait for the receiver to submit their vouchers
ev := events.NewEvents(ctx, paymentCreator)
Expand Down
66 changes: 66 additions & 0 deletions blockstore/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package blockstore

import (
"context"

blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
)

type ChainIO interface {
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
ChainHasObj(context.Context, cid.Cid) (bool, error)
}

type apiBlockstore struct {
api ChainIO
}

// This blockstore is adapted in the constructor.
var _ BasicBlockstore = (*apiBlockstore)(nil)

func NewAPIBlockstore(cio ChainIO) Blockstore {
bs := &apiBlockstore{api: cio}
return Adapt(bs) // return an adapted blockstore.
}

func (a *apiBlockstore) DeleteBlock(cid.Cid) error {
return xerrors.New("not supported")
}

func (a *apiBlockstore) Has(c cid.Cid) (bool, error) {
return a.api.ChainHasObj(context.TODO(), c)
}

func (a *apiBlockstore) Get(c cid.Cid) (blocks.Block, error) {
bb, err := a.api.ChainReadObj(context.TODO(), c)
if err != nil {
return nil, err
}
return blocks.NewBlockWithCid(bb, c)
}

func (a *apiBlockstore) GetSize(c cid.Cid) (int, error) {
bb, err := a.api.ChainReadObj(context.TODO(), c)
if err != nil {
return 0, err
}
return len(bb), nil
}

func (a *apiBlockstore) Put(blocks.Block) error {
return xerrors.New("not supported")
}

func (a *apiBlockstore) PutMany([]blocks.Block) error {
return xerrors.New("not supported")
}

func (a *apiBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
return nil, xerrors.New("not supported")
}

func (a *apiBlockstore) HashOnRead(enabled bool) {
return
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
logger "github.com/ipfs/go-log/v2"
pool "github.com/libp2p/go-buffer-pool"

"github.com/filecoin-project/lotus/lib/blockstore"
"github.com/filecoin-project/lotus/blockstore"
)

var (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import (
"testing"

blocks "github.com/ipfs/go-block-format"
blockstore "github.com/ipfs/go-ipfs-blockstore"
"github.com/stretchr/testify/require"

"github.com/filecoin-project/lotus/blockstore"
)

func TestBadgerBlockstore(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"
"testing"

"github.com/filecoin-project/lotus/lib/blockstore"
"github.com/filecoin-project/lotus/blockstore"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
u "github.com/ipfs/go-ipfs-util"
Expand Down
66 changes: 66 additions & 0 deletions blockstore/blockstore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package blockstore

import (
"github.com/ipfs/go-cid"
ds "github.com/ipfs/go-datastore"
logging "github.com/ipfs/go-log/v2"

blockstore "github.com/ipfs/go-ipfs-blockstore"
)

var log = logging.Logger("blockstore")

var ErrNotFound = blockstore.ErrNotFound

// Blockstore is the blockstore interface used by Lotus. It is the union
// of the basic go-ipfs blockstore, with other capabilities required by Lotus,
// e.g. View or Sync.
type Blockstore interface {
blockstore.Blockstore
blockstore.Viewer
}

// BasicBlockstore is an alias to the original IPFS Blockstore.
type BasicBlockstore = blockstore.Blockstore

type Viewer = blockstore.Viewer

// WrapIDStore wraps the underlying blockstore in an "identity" blockstore.
// The ID store filters out all puts for blocks with CIDs using the "identity"
// hash function. It also extracts inlined blocks from CIDs using the identity
// hash function and returns them on get/has, ignoring the contents of the
// blockstore.
func WrapIDStore(bstore blockstore.Blockstore) Blockstore {
return blockstore.NewIdStore(bstore).(Blockstore)
}

// FromDatastore creates a new blockstore backed by the given datastore.
func FromDatastore(dstore ds.Batching) Blockstore {
return WrapIDStore(blockstore.NewBlockstore(dstore))
}

type adaptedBlockstore struct {
blockstore.Blockstore
}

var _ Blockstore = (*adaptedBlockstore)(nil)

func (a *adaptedBlockstore) View(cid cid.Cid, callback func([]byte) error) error {
blk, err := a.Get(cid)
if err != nil {
return err
}
return callback(blk.RawData())
}

// Adapt adapts a standard blockstore to a Lotus blockstore by
// enriching it with the extra methods that Lotus requires (e.g. View, Sync).
//
// View proxies over to Get and calls the callback with the value supplied by Get.
// Sync noops.
func Adapt(bs blockstore.Blockstore) Blockstore {
if ret, ok := bs.(Blockstore); ok {
return ret
}
return &adaptedBlockstore{bs}
raulk marked this conversation as resolved.
Show resolved Hide resolved
}
Loading