deals: Verify network message signatures

This commit is contained in:
Łukasz Magiera 2019-11-07 15:09:11 +01:00
parent 2588a6a7eb
commit 58472afa3a
8 changed files with 54 additions and 47 deletions

View File

@ -404,7 +404,7 @@ func (t *ClientDealProposal) MarshalCBOR(w io.Writer) error {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{135}); err != nil {
if _, err := w.Write([]byte{136}); err != nil {
return err
}
@ -439,6 +439,11 @@ func (t *ClientDealProposal) MarshalCBOR(w io.Writer) error {
return err
}
// t.t.MinerWorker (address.Address) (struct)
if err := t.MinerWorker.MarshalCBOR(w); err != nil {
return err
}
// t.t.MinerID (peer.ID) (string)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.MinerID)))); err != nil {
return err
@ -460,7 +465,7 @@ func (t *ClientDealProposal) UnmarshalCBOR(r io.Reader) error {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 7 {
if extra != 8 {
return fmt.Errorf("cbor input had wrong number of fields")
}
@ -522,6 +527,15 @@ func (t *ClientDealProposal) UnmarshalCBOR(r io.Reader) error {
return err
}
}
// t.t.MinerWorker (address.Address) (struct)
{
if err := t.MinerWorker.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.MinerID (peer.ID) (string)
@ -541,7 +555,7 @@ func (t *ClientDeal) MarshalCBOR(w io.Writer) error {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{134}); err != nil {
if _, err := w.Write([]byte{135}); err != nil {
return err
}
@ -569,6 +583,11 @@ func (t *ClientDeal) MarshalCBOR(w io.Writer) error {
return err
}
// t.t.MinerWorker (address.Address) (struct)
if err := t.MinerWorker.MarshalCBOR(w); err != nil {
return err
}
// t.t.DealID (uint64) (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.DealID))); err != nil {
return err
@ -600,7 +619,7 @@ func (t *ClientDeal) UnmarshalCBOR(r io.Reader) error {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 6 {
if extra != 7 {
return fmt.Errorf("cbor input had wrong number of fields")
}
@ -645,6 +664,15 @@ func (t *ClientDeal) UnmarshalCBOR(r io.Reader) error {
t.Miner = peer.ID(sval)
}
// t.t.MinerWorker (address.Address) (struct)
{
if err := t.MinerWorker.UnmarshalCBOR(br); err != nil {
return err
}
}
// t.t.DealID (uint64) (uint64)
maj, extra, err = cbg.CborReadHeader(br)

View File

@ -35,6 +35,7 @@ type ClientDeal struct {
Proposal actors.StorageDealProposal
State api.DealState
Miner peer.ID
MinerWorker address.Address
DealID uint64
PublishMessage *cid.Cid
@ -178,6 +179,7 @@ type ClientDealProposal struct {
ProviderAddress address.Address
Client address.Address
MinerWorker address.Address
MinerID peer.ID
}
@ -256,6 +258,7 @@ func (c *Client) Start(ctx context.Context, p ClientDealProposal) (cid.Cid, erro
Proposal: *dealProposal,
State: api.DealUnknown,
Miner: p.MinerID,
MinerWorker: p.MinerWorker,
s: s,
}

View File

@ -220,6 +220,5 @@ func (c *Client) sealing(ctx context.Context, deal ClientDeal) (func(*ClientDeal
return nil, xerrors.Errorf("failed to set up called handler")
}
log.Info("DEAL COMPLETE!!")
return nil, nil
}

View File

@ -77,7 +77,9 @@ func (c *Client) readStorageDealResp(deal ClientDeal) (*Response, error) {
return nil, err
}
// TODO: verify signature
if err := resp.Verify(deal.MinerWorker); err != nil {
return nil, xerrors.Errorf("verifying response signature failed", err)
}
if resp.Response.Proposal != deal.ProposalCid {
return nil, xerrors.Errorf("miner responded to a wrong proposal: %s != %s", resp.Response.Proposal, deal.ProposalCid)

View File

@ -85,7 +85,6 @@ func (p *Provider) accept(ctx context.Context, deal MinerDeal) (func(*MinerDeal)
// TODO: check StorageCollateral
// TODO:
minPrice := types.BigDiv(types.BigMul(p.ask.Ask.Price, types.NewInt(deal.Proposal.PieceSize)), types.NewInt(1<<30))
if deal.Proposal.StoragePricePerEpoch.LessThan(minPrice) {
return nil, xerrors.Errorf("storage price per epoch less than asking price: %s < %s", deal.Proposal.StoragePricePerEpoch, minPrice)
@ -239,33 +238,12 @@ func (p *Provider) sealing(ctx context.Context, deal MinerDeal) (func(*MinerDeal
if err := p.sminer.SealSector(ctx, deal.SectorID); err != nil {
return nil, xerrors.Errorf("sealing sector failed: %w", err)
}
// TODO: Let's not care after this point, for now at least, client can watch the chain
/*_, err = p.waitSealed(ctx, deal)
if err != nil {
return nil, err
}*/
return nil, nil
}
func (p *Provider) complete(ctx context.Context, deal MinerDeal) (func(*MinerDeal), error) {
/*mcid, err := p.commt.WaitCommit(ctx, deal.Proposal.Provider, deal.SectorID)
if err != nil {
log.Warnf("Waiting for sector commitment message: %s", err)
}*/
//panic("fixme")
/*err = p.sendSignedResponse(&Response{
State: api.DealComplete,
Proposal: deal.ProposalCid,
CommitMessage: &mcid,
})
if err != nil {
log.Warnf("Sending deal response failed: %s", err)
}*/
// TODO: observe sector lifecycle, status, expiration..
return nil, nil
}

View File

@ -54,9 +54,6 @@ func (p *Provider) readProposal(s inet.Stream) (proposal Proposal, err error) {
return proposal, xerrors.Errorf("verifying StorageDealProposal: %w", err)
}
// TODO: Validate proposal maybe
// (and signature, obviously)
if proposal.DealProposal.Provider != p.actor {
log.Errorf("proposal with wrong ProviderAddress: %s", proposal.DealProposal.Provider)
return proposal, err

View File

@ -5,6 +5,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/cborrpc"
"github.com/ipfs/go-cid"
)
@ -36,6 +37,15 @@ type SignedResponse struct {
Signature *types.Signature
}
func (r *SignedResponse) Verify(addr address.Address) error {
b, err := cborrpc.Dump(&r.Response)
if err != nil {
return err
}
return r.Signature.Verify(addr, b)
}
type AskRequest struct {
Miner address.Address
}

View File

@ -24,7 +24,6 @@ import (
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/deals"
"github.com/filecoin-project/lotus/chain/store"
@ -61,24 +60,14 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.A
return nil, xerrors.Errorf("failed to get default address: %w", err)
}
// get miner peerID
msg := &types.Message{
To: miner,
From: miner,
Method: actors.MAMethods.GetPeerID,
}
r, err := a.StateCall(ctx, msg, nil)
pid, err := a.StateMinerPeerID(ctx, miner, nil)
if err != nil {
return nil, xerrors.Errorf("failed getting peer ID: %w", err)
}
if r.ExitCode != 0 {
return nil, xerrors.Errorf("call to get peer ID for miner failed: exit code %d", r.ExitCode)
}
pid, err := peer.IDFromBytes(r.Return)
mw, err := a.StateMinerWorker(ctx, miner, nil)
if err != nil {
return nil, xerrors.Errorf("parsing peer ID wrong: %w", err)
return nil, xerrors.Errorf("failed getting miner worker: %w", err)
}
proposal := deals.ClientDealProposal{
@ -86,8 +75,9 @@ func (a *API) ClientStartDeal(ctx context.Context, data cid.Cid, miner address.A
PricePerEpoch: epochPrice,
ProposalExpiration: math.MaxUint64, // TODO: set something reasonable
Duration: blocksDuration,
ProviderAddress: miner,
Client: self,
ProviderAddress: miner,
MinerWorker: mw,
MinerID: pid,
}