deals: Cleanup client a bit
This commit is contained in:
parent
25dbdd761a
commit
821e03bcd7
@ -2,10 +2,7 @@ package deals
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"math"
|
"math"
|
||||||
"os"
|
|
||||||
|
|
||||||
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
@ -16,6 +13,7 @@ import (
|
|||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
unixfile "github.com/ipfs/go-unixfs/file"
|
unixfile "github.com/ipfs/go-unixfs/file"
|
||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
|
inet "github.com/libp2p/go-libp2p-core/network"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -101,46 +99,92 @@ func (c *Client) Run() {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Start(ctx context.Context, data cid.Cid, totalPrice types.BigInt, from address.Address, miner address.Address, minerID peer.ID, blocksDuration uint64) (cid.Cid, error) {
|
func (c *Client) commP(ctx context.Context, data cid.Cid) ([]byte, int64, error) {
|
||||||
// TODO: Eww
|
|
||||||
root, err := c.dag.Get(ctx, data)
|
root, err := c.dag.Get(ctx, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to get file root for deal: %s", err)
|
log.Errorf("failed to get file root for deal: %s", err)
|
||||||
return cid.Undef, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err := unixfile.NewUnixfsFile(ctx, c.dag, root)
|
n, err := unixfile.NewUnixfsFile(ctx, c.dag, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("cannot open unixfs file: %s", err)
|
log.Errorf("cannot open unixfs file: %s", err)
|
||||||
return cid.Undef, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
uf, ok := n.(files.File)
|
uf, ok := n.(files.File)
|
||||||
if !ok {
|
if !ok {
|
||||||
// TODO: we probably got directory, how should we handle this in unixfs mode?
|
// TODO: we probably got directory, how should we handle this in unixfs mode?
|
||||||
return cid.Undef, xerrors.New("unsupported unixfs type")
|
return nil, 0, xerrors.New("unsupported unixfs type")
|
||||||
}
|
}
|
||||||
|
|
||||||
size, err := uf.Size()
|
size, err := uf.Size()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Cid{}, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := ioutil.TempFile(os.TempDir(), "commP-temp-")
|
var commP [sectorbuilder.CommitmentBytesLen]byte
|
||||||
|
err = withTemp(uf, func(f string) error {
|
||||||
|
commP, err = sectorbuilder.GeneratePieceCommitment(f, uint64(size))
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
return commP[:], size, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) sendProposal(s inet.Stream, proposal StorageDealProposal, from address.Address) error {
|
||||||
|
log.Info("Sending deal proposal")
|
||||||
|
|
||||||
|
msg, err := cbor.DumpObject(proposal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.Copy(f, uf); err != nil {
|
sig, err := c.w.Sign(from, msg)
|
||||||
return cid.Undef, err
|
|
||||||
}
|
|
||||||
if err := f.Close(); err != nil {
|
|
||||||
return cid.Undef, err
|
|
||||||
}
|
|
||||||
commP, err := sectorbuilder.GeneratePieceCommitment(f.Name(), uint64(size))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return err
|
||||||
}
|
}
|
||||||
if err := os.Remove(f.Name()); err != nil {
|
|
||||||
|
signedProposal := &SignedStorageDealProposal{
|
||||||
|
Proposal: proposal,
|
||||||
|
Signature: sig,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cborrpc.WriteCborRPC(s, signedProposal)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) waitAccept(s inet.Stream, proposal StorageDealProposal, minerID peer.ID) (ClientDeal, error) {
|
||||||
|
log.Info("Waiting for response")
|
||||||
|
|
||||||
|
var resp SignedStorageDealResponse
|
||||||
|
if err := cborrpc.ReadCborRPC(s, &resp); err != nil {
|
||||||
|
log.Errorw("failed to read StorageDealResponse message", "error", err)
|
||||||
|
return ClientDeal{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: verify signature
|
||||||
|
|
||||||
|
if resp.Response.State != Accepted {
|
||||||
|
return ClientDeal{}, xerrors.Errorf("Deal wasn't accepted (State=%d)", resp.Response.State)
|
||||||
|
}
|
||||||
|
|
||||||
|
proposalNd, err := cbor.WrapObject(proposal, math.MaxUint64, -1)
|
||||||
|
if err != nil {
|
||||||
|
return ClientDeal{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.Response.Proposal != proposalNd.Cid() {
|
||||||
|
return ClientDeal{}, xerrors.New("miner responded to a wrong proposal")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ClientDeal{
|
||||||
|
ProposalCid: proposalNd.Cid(),
|
||||||
|
Status: DealResolvingMiner,
|
||||||
|
Miner: minerID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Start(ctx context.Context, data cid.Cid, totalPrice types.BigInt, from address.Address, miner address.Address, minerID peer.ID, blocksDuration uint64) (cid.Cid, error) {
|
||||||
|
commP, size, err := c.commP(ctx, data)
|
||||||
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +195,7 @@ func (c *Client) Start(ctx context.Context, data cid.Cid, totalPrice types.BigIn
|
|||||||
PieceRef: data.String(),
|
PieceRef: data.String(),
|
||||||
SerializationMode: SerializationUnixFs,
|
SerializationMode: SerializationUnixFs,
|
||||||
CommP: commP[:],
|
CommP: commP[:],
|
||||||
Size: 6,
|
Size: uint64(size),
|
||||||
TotalPrice: totalPrice,
|
TotalPrice: totalPrice,
|
||||||
Duration: blocksDuration,
|
Duration: blocksDuration,
|
||||||
Payment: PaymentInfo{
|
Payment: PaymentInfo{
|
||||||
@ -168,57 +212,22 @@ func (c *Client) Start(ctx context.Context, data cid.Cid, totalPrice types.BigIn
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
defer s.Close() // TODO: not too soon?
|
defer s.Reset() // TODO: handle other updates
|
||||||
|
|
||||||
log.Info("Sending deal proposal")
|
if err := c.sendProposal(s, proposal, from); err != nil {
|
||||||
|
|
||||||
msg, err := cbor.DumpObject(proposal)
|
|
||||||
if err != nil {
|
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
sig, err := c.w.Sign(from, msg)
|
|
||||||
|
deal, err := c.waitAccept(s, proposal, minerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
signedProposal := &SignedStorageDealProposal{
|
log.Info("DEAL ACCEPTED!")
|
||||||
Proposal: proposal,
|
|
||||||
Signature: sig,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := cborrpc.WriteCborRPC(s, signedProposal); err != nil {
|
// TODO: actually care about what happens with the deal after it was accepted
|
||||||
return cid.Undef, err
|
//c.incoming <- deal
|
||||||
}
|
return deal.ProposalCid, nil
|
||||||
|
|
||||||
log.Info("Reading response")
|
|
||||||
|
|
||||||
var resp SignedStorageDealResponse
|
|
||||||
if err := cborrpc.ReadCborRPC(s, &resp); err != nil {
|
|
||||||
log.Errorw("failed to read StorageDealResponse message", "error", err)
|
|
||||||
return cid.Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: verify signature
|
|
||||||
|
|
||||||
if resp.Response.State != Accepted {
|
|
||||||
return cid.Undef, xerrors.Errorf("Deal wasn't accepted (State=%d)", resp.Response.State)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("Registering deal")
|
|
||||||
|
|
||||||
proposalNd, err := cbor.WrapObject(proposal, math.MaxUint64, -1)
|
|
||||||
if err != nil {
|
|
||||||
return cid.Undef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
deal := ClientDeal{
|
|
||||||
ProposalCid: proposalNd.Cid(),
|
|
||||||
Status: DealResolvingMiner,
|
|
||||||
Miner: minerID,
|
|
||||||
}
|
|
||||||
|
|
||||||
c.incoming <- deal
|
|
||||||
return proposalNd.Cid(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Stop() {
|
func (c *Client) Stop() {
|
||||||
|
@ -59,7 +59,7 @@ func (h *Handler) staged(ctx context.Context, deal MinerDeal) error {
|
|||||||
Proposal: deal.ProposalCid,
|
Proposal: deal.ProposalCid,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
log.Warnf("Sending deal response failed: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
root, err := h.dag.Get(ctx, deal.Ref)
|
root, err := h.dag.Get(ctx, deal.Ref)
|
||||||
|
@ -21,7 +21,7 @@ func (h *Handler) failDeal(id cid.Cid, cerr error) {
|
|||||||
cerr = xerrors.Errorf("unknown error (fail called at %s:%d)", f, l)
|
cerr = xerrors.Errorf("unknown error (fail called at %s:%d)", f, l)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Error("Deal %s failed: %s", id, cerr)
|
log.Errorf("deal %s failed: %s", id, cerr)
|
||||||
|
|
||||||
err := h.sendSignedResponse(StorageDealResponse{
|
err := h.sendSignedResponse(StorageDealResponse{
|
||||||
State: Failed,
|
State: Failed,
|
||||||
@ -76,7 +76,7 @@ func (h *Handler) sendSignedResponse(resp StorageDealResponse) error {
|
|||||||
if len(def) != 1 {
|
if len(def) != 1 {
|
||||||
// NOTE: If this ever happens for a good reason, implement this with GetWorker on the miner actor
|
// NOTE: If this ever happens for a good reason, implement this with GetWorker on the miner actor
|
||||||
// TODO: implement with GetWorker on the miner actor
|
// TODO: implement with GetWorker on the miner actor
|
||||||
return xerrors.Errorf("Expected only 1 address in wallet, got %d", len(def))
|
return xerrors.Errorf("expected only 1 address in wallet, got %d", len(def))
|
||||||
}
|
}
|
||||||
|
|
||||||
sig, err := h.w.Sign(def[0], msg)
|
sig, err := h.w.Sign(def[0], msg)
|
||||||
|
Loading…
Reference in New Issue
Block a user