Add method to query latest deal state

This commit is contained in:
whyrusleeping 2019-11-06 11:44:28 -08:00 committed by Łukasz Magiera
parent 7cb4148b18
commit 597dbe369c
6 changed files with 65 additions and 14 deletions

View File

@ -2,6 +2,7 @@ package api
import ( import (
"context" "context"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/ipfs/go-filestore" "github.com/ipfs/go-filestore"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
@ -73,6 +74,7 @@ type FullNode interface {
// ClientImport imports file under the specified path into filestore // ClientImport imports file under the specified path into filestore
ClientImport(ctx context.Context, path string) (cid.Cid, error) ClientImport(ctx context.Context, path string) (cid.Cid, error)
ClientStartDeal(ctx context.Context, data cid.Cid, miner address.Address, epochPrice types.BigInt, blocksDuration uint64) (*cid.Cid, error) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.Address, epochPrice types.BigInt, blocksDuration uint64) (*cid.Cid, error)
ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error)
ClientListDeals(ctx context.Context) ([]DealInfo, error) ClientListDeals(ctx context.Context) ([]DealInfo, error)
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error) // TODO: specify serialization mode we want (defaults to unixfs for now) ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error) // TODO: specify serialization mode we want (defaults to unixfs for now)

View File

@ -82,6 +82,7 @@ type FullNodeStruct struct {
ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, error) `perm:"write"` ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, error) `perm:"write"`
ClientFindData func(ctx context.Context, root cid.Cid) ([]QueryOffer, error) `perm:"read"` ClientFindData func(ctx context.Context, root cid.Cid) ([]QueryOffer, error) `perm:"read"`
ClientStartDeal func(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) `perm:"admin"` ClientStartDeal func(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) `perm:"admin"`
ClientGetDealInfo func(context.Context, cid.Cid) (*DealInfo, error) `perm:"read"`
ClientListDeals func(ctx context.Context) ([]DealInfo, error) `perm:"write"` ClientListDeals func(ctx context.Context) ([]DealInfo, error) `perm:"write"`
ClientRetrieve func(ctx context.Context, order RetrievalOrder, path string) error `perm:"admin"` ClientRetrieve func(ctx context.Context, order RetrievalOrder, path string) error `perm:"admin"`
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"` ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"`
@ -193,6 +194,9 @@ func (c *FullNodeStruct) ClientFindData(ctx context.Context, root cid.Cid) ([]Qu
func (c *FullNodeStruct) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) { func (c *FullNodeStruct) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.Address, price types.BigInt, blocksDuration uint64) (*cid.Cid, error) {
return c.Internal.ClientStartDeal(ctx, data, miner, price, blocksDuration) return c.Internal.ClientStartDeal(ctx, data, miner, price, blocksDuration)
} }
func (c *FullNodeStruct) ClientGetDealInfo(ctx context.Context, deal cid.Cid) (*DealInfo, error) {
return c.Internal.ClientGetDealInfo(ctx, deal)
}
func (c *FullNodeStruct) ClientListDeals(ctx context.Context) ([]DealInfo, error) { func (c *FullNodeStruct) ClientListDeals(ctx context.Context) ([]DealInfo, error) {
return c.Internal.ClientListDeals(ctx) return c.Internal.ClientListDeals(ctx)

View File

@ -8,17 +8,19 @@ import (
"testing" "testing"
"time" "time"
logging "github.com/ipfs/go-log"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/impl" "github.com/filecoin-project/lotus/node/impl"
) )
func TestDealFlow(t *testing.T, b APIBuilder) { func TestDealFlow(t *testing.T, b APIBuilder) {
logging.SetAllLoggers(logging.LevelInfo)
ctx := context.TODO() ctx := context.TODO()
n, sn := b(t, 1, []int{0}) n, sn := b(t, 1, []int{0})
client := n[0].FullNode.(*impl.FullNodeAPI) client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0] miner := sn[0]
_ = miner
addrinfo, err := client.NetAddrsListen(ctx) addrinfo, err := client.NetAddrsListen(ctx)
if err != nil { if err != nil {
@ -44,24 +46,29 @@ func TestDealFlow(t *testing.T, b APIBuilder) {
fmt.Println("FILE CID: ", fcid) fmt.Println("FILE CID: ", fcid)
go func() { go func() {
time.Sleep(time.Second) for i := 0; i < 4; i++ {
fmt.Println("mining a block now") time.Sleep(time.Second)
if err := n[0].MineOne(ctx); err != nil { fmt.Println("mining a block now", i)
t.Fatal(err) if err := n[0].MineOne(ctx); err != nil {
t.Fatal(err)
}
} }
fmt.Println("mined a block")
time.Sleep(time.Second)
fmt.Println("mining a block now")
if err := n[0].MineOne(ctx); err != nil {
t.Fatal(err)
}
}() }()
deal, err := client.ClientStartDeal(ctx, fcid, maddr, types.NewInt(1), 100) deal, err := client.ClientStartDeal(ctx, fcid, maddr, types.NewInt(200), 100)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
time.Sleep(time.Second)
for {
di, err := client.ClientGetDealInfo(ctx, *deal)
if err != nil {
t.Fatal(err)
}
fmt.Println("DEAL STATE: ", *deal, di.State)
time.Sleep(time.Second / 2)
}
fmt.Println("Deal done!", deal) fmt.Println("Deal done!", deal)
time.Sleep(time.Second * 10) time.Sleep(time.Second * 10)

View File

@ -298,6 +298,14 @@ func (c *Client) List() ([]ClientDeal, error) {
return out, nil return out, nil
} }
func (c *Client) GetDeal(d cid.Cid) (*ClientDeal, error) {
var out ClientDeal
if err := c.deals.Get(d, &out); err != nil {
return nil, err
}
return &out, nil
}
func (c *Client) Stop() { func (c *Client) Stop() {
close(c.stop) close(c.stop)
<-c.stopped <-c.stopped

View File

@ -7,6 +7,7 @@ import (
"github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/query" "github.com/ipfs/go-datastore/query"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/lib/cborrpc" "github.com/filecoin-project/lotus/lib/cborrpc"
@ -110,6 +111,19 @@ func (st *StateStore) mutate(i interface{}, mutator func([]byte) ([]byte, error)
return st.ds.Put(k, mutated) return st.ds.Put(k, mutated)
} }
func (st *StateStore) Get(i interface{}, out cbg.CBORUnmarshaler) error {
k := toKey(i)
val, err := st.ds.Get(k)
if err != nil {
if xerrors.Is(err, datastore.ErrNotFound) {
return xerrors.Errorf("No state for %s", i)
}
return err
}
return out.UnmarshalCBOR(bytes.NewReader(val))
}
// out: *[]T // out: *[]T
func (st *StateStore) List(out interface{}) error { func (st *StateStore) List(out interface{}) error {
res, err := st.ds.Query(query.Query{}) res, err := st.ds.Query(query.Query{})

View File

@ -124,6 +124,22 @@ func (a *API) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) {
return out, nil return out, nil
} }
func (a *API) ClientGetDealInfo(ctx context.Context, d cid.Cid) (*api.DealInfo, error) {
v, err := a.DealClient.GetDeal(d)
if err != nil {
return nil, err
}
return &api.DealInfo{
ProposalCid: v.ProposalCid,
State: v.State,
Provider: v.Proposal.Provider,
PieceRef: v.Proposal.PieceRef,
Size: v.Proposal.PieceSize,
PricePerEpoch: v.Proposal.StoragePricePerEpoch,
Duration: v.Proposal.Duration,
}, nil
}
func (a *API) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) { func (a *API) ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) {
// TODO: check if we have the ENTIRE dag // TODO: check if we have the ENTIRE dag