From cdd91914b9ad07a439af123e6de7c33206d9da84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 23 Oct 2019 20:04:07 +0200 Subject: [PATCH] on chain deals: Actually set DataSize --- chain/deals/cbor_gen.go | 19 ++----------------- chain/deals/client.go | 9 +++++---- chain/deals/client_utils.go | 25 +++++++++++++++++++++++++ chain/deals/provider_states.go | 10 ++++++++++ lotuspond/front/src/ChainExplorer.js | 8 ++++++-- node/impl/client/client.go | 12 ++++++------ 6 files changed, 54 insertions(+), 29 deletions(-) diff --git a/chain/deals/cbor_gen.go b/chain/deals/cbor_gen.go index 41342d56f..23a79eabb 100644 --- a/chain/deals/cbor_gen.go +++ b/chain/deals/cbor_gen.go @@ -409,7 +409,7 @@ func (t *ClientDealProposal) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{136}); err != nil { + if _, err := w.Write([]byte{135}); err != nil { return err } @@ -419,11 +419,6 @@ func (t *ClientDealProposal) MarshalCBOR(w io.Writer) error { return xerrors.Errorf("failed to write cid field t.Data: %w", err) } - // t.t.DataSize (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.DataSize)); err != nil { - return err - } - // t.t.TotalPrice (types.BigInt) if err := t.TotalPrice.MarshalCBOR(w); err != nil { return err @@ -470,7 +465,7 @@ func (t *ClientDealProposal) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 8 { + if extra != 7 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -486,16 +481,6 @@ func (t *ClientDealProposal) UnmarshalCBOR(r io.Reader) error { t.Data = c } - // t.t.DataSize (uint64) - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.DataSize = extra // t.t.TotalPrice (types.BigInt) { diff --git a/chain/deals/client.go b/chain/deals/client.go index b43593437..b6e0b3df5 100644 --- a/chain/deals/client.go +++ b/chain/deals/client.go @@ -157,8 +157,7 @@ func (c *Client) onUpdated(ctx context.Context, update clientDealUpdate) { } type ClientDealProposal struct { - Data cid.Cid - DataSize uint64 + Data cid.Cid TotalPrice types.BigInt ProposalExpiration uint64 @@ -201,16 +200,18 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro } } + dataSize, err := c.dataSize(ctx, p.Data) + proposal := &actors.StorageDealProposal{ PieceRef: p.Data.Bytes(), - PieceSize: p.DataSize, + PieceSize: uint64(dataSize), PieceSerialization: actors.SerializationUnixFSv0, Client: p.Client, Provider: p.ProviderAddress, ProposalExpiration: p.ProposalExpiration, Duration: p.Duration, StoragePrice: p.TotalPrice, - StorageCollateral: types.NewInt(p.DataSize), // TODO: real calc + StorageCollateral: types.NewInt(uint64(dataSize)), // TODO: real calc } if err := api.SignWith(ctx, c.w.Sign, p.Client, proposal); err != nil { diff --git a/chain/deals/client_utils.go b/chain/deals/client_utils.go index eb05cb8ca..9c26f4268 100644 --- a/chain/deals/client_utils.go +++ b/chain/deals/client_utils.go @@ -1,9 +1,12 @@ package deals import ( + "context" "runtime" "github.com/ipfs/go-cid" + files "github.com/ipfs/go-ipfs-files" + unixfile "github.com/ipfs/go-unixfs/file" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/lib/cborrpc" @@ -25,6 +28,28 @@ func (c *Client) failDeal(id cid.Cid, cerr error) { log.Errorf("deal %s failed: %s", id, cerr) } +func (c *Client) dataSize(ctx context.Context, data cid.Cid) (int64, error) { + root, err := c.dag.Get(ctx, data) + if err != nil { + log.Errorf("failed to get file root for deal: %s", err) + return 0, err + } + + n, err := unixfile.NewUnixfsFile(ctx, c.dag, root) + if err != nil { + log.Errorf("cannot open unixfs file: %s", err) + return 0, err + } + + uf, ok := n.(files.File) + if !ok { + // TODO: we probably got directory, how should we handle this in unixfs mode? + return 0, xerrors.New("unsupported unixfs type") + } + + return uf.Size() +} + func (c *Client) readStorageDealResp(deal ClientDeal) (*Response, error) { s, ok := c.conns[deal.ProposalCid] if !ok { diff --git a/chain/deals/provider_states.go b/chain/deals/provider_states.go index c2de1c9c0..c604d004b 100644 --- a/chain/deals/provider_states.go +++ b/chain/deals/provider_states.go @@ -195,6 +195,16 @@ func (p *Provider) staged(ctx context.Context, deal MinerDeal) (func(*MinerDeal) return nil, xerrors.Errorf("unsupported unixfs file type") } + // TODO: uf.Size() is user input, not trusted + // This won't be useful / here after we migrate to putting CARs into sectors + size, err := uf.Size() + if err != nil { + return nil, xerrors.Errorf("getting unixfs file size: %w", err) + } + if uint64(size) != deal.Proposal.PieceSize { + return nil, xerrors.Errorf("deal.Proposal.PieceSize didn't match unixfs file size") + } + pcid, err := cid.Cast(deal.Proposal.PieceRef) if err != nil { return nil, err diff --git a/lotuspond/front/src/ChainExplorer.js b/lotuspond/front/src/ChainExplorer.js index aec6697bc..1f8f619c0 100644 --- a/lotuspond/front/src/ChainExplorer.js +++ b/lotuspond/front/src/ChainExplorer.js @@ -71,10 +71,10 @@ class ChainExplorer extends React.Component { return } if(!base.Blocks) { - console.log("base for H is nll blk", h, base) + console.log("base for H is nil blk", h, base) return } - let cids = base.Blocks.map(b => b.Parents) + let cids = base.Blocks.map(b => (b.Parents || [])) .reduce((acc, val) => { let out = {...acc} val.forEach(c => out[c['/']] = 8) @@ -85,6 +85,10 @@ class ChainExplorer extends React.Component { const blocks = await Promise.all(cids.map(cid => this.props.client.call('Filecoin.ChainGetBlock', [cid]))) + if (!blocks[0]) { + return + } + cache[h] = { Height: blocks[0].Height, Cids: cids, diff --git a/node/impl/client/client.go b/node/impl/client/client.go index b6103d3d7..926d6f623 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -80,13 +80,13 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.A total := types.BigMul(price, types.NewInt(blocksDuration)) proposal := deals.ClientDealProposal{ - Data: data, - TotalPrice: total, + Data: data, + TotalPrice: total, ProposalExpiration: math.MaxUint64, // TODO: set something reasonable - Duration: blocksDuration, - ProviderAddress: miner, - Client: self, - MinerID: pid, + Duration: blocksDuration, + ProviderAddress: miner, + Client: self, + MinerID: pid, } c, err := a.DealClient.Start(ctx, proposal)