Skip to content

Commit

Permalink
feat: add v1.1.1 of deal proposal protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkmc committed Jun 20, 2022
1 parent 568e7a4 commit fd8afb8
Show file tree
Hide file tree
Showing 14 changed files with 380 additions and 93 deletions.
12 changes: 6 additions & 6 deletions shared_testutil/test_network_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ func StubbedDealPaymentReader(payment rm.DealPayment) DealPaymentReader {
}

// StorageDealProposalReader is a function to mock reading deal proposals.
type StorageDealProposalReader func() (smnet.Proposal, error)
type StorageDealProposalReader func() (smnet.Proposal, cid.Cid, error)

// StorageDealResponseReader is a function to mock reading deal responses.
type StorageDealResponseReader func() (smnet.SignedResponse, []byte, error)
Expand Down Expand Up @@ -460,7 +460,7 @@ func NewTestStorageDealStream(params TestStorageDealStreamParams) *TestStorageDe
}

// ReadDealProposal calls the mocked deal proposal reader function.
func (tsds *TestStorageDealStream) ReadDealProposal() (smnet.Proposal, error) {
func (tsds *TestStorageDealStream) ReadDealProposal() (smnet.Proposal, cid.Cid, error) {
return tsds.proposalReader()
}

Expand Down Expand Up @@ -489,8 +489,8 @@ func (tsds *TestStorageDealStream) Close() error {
}

// TrivialStorageDealProposalReader succeeds trivially, returning an empty proposal.
func TrivialStorageDealProposalReader() (smnet.Proposal, error) {
return smnet.Proposal{}, nil
func TrivialStorageDealProposalReader() (smnet.Proposal, cid.Cid, error) {
return smnet.Proposal{}, cid.Undef, nil
}

// TrivialStorageDealResponseReader succeeds trivially, returning an empty deal response.
Expand All @@ -510,8 +510,8 @@ func TrivialStorageDealResponseWriter(smnet.SignedResponse, smnet.ResigningFunc)

// StubbedStorageProposalReader returns the given proposal when called
func StubbedStorageProposalReader(proposal smnet.Proposal) StorageDealProposalReader {
return func() (smnet.Proposal, error) {
return proposal, nil
return func() (smnet.Proposal, cid.Cid, error) {
return proposal, cid.Undef, nil
}
}

Expand Down
17 changes: 6 additions & 11 deletions storagemarket/impl/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func (p *Provider) HandleDealStream(s network.StorageDealStream) {
}

func (p *Provider) receiveDeal(s network.StorageDealStream) error {
proposal, err := s.ReadDealProposal()
proposal, propCid, err := s.ReadDealProposal()
if err != nil {
return xerrors.Errorf("failed to read proposal message: %w", err)
}
Expand All @@ -265,14 +265,9 @@ func (p *Provider) receiveDeal(s network.StorageDealStream) error {
return xerrors.Errorf("failed to get deal proposal from proposal message")
}

proposalNd, err := cborutil.AsIpld(proposal.DealProposal)
if err != nil {
return err
}

// Check if we are already tracking this deal
var md storagemarket.MinerDeal
if err := p.deals.Get(proposalNd.Cid()).Get(&md); err == nil {
if err := p.deals.Get(propCid).Get(&md); err == nil {
// We are already tracking this deal, for some reason it was re-proposed, perhaps because of a client restart
// this is ok, just send a response back.
return p.resendProposalResponse(s, &md)
Expand Down Expand Up @@ -300,23 +295,23 @@ func (p *Provider) receiveDeal(s network.StorageDealStream) error {
Client: s.RemotePeer(),
Miner: p.net.ID(),
ClientDealProposal: *proposal.DealProposal,
ProposalCid: proposalNd.Cid(),
ProposalCid: propCid,
State: storagemarket.StorageDealUnknown,
Ref: proposal.Piece,
FastRetrieval: proposal.FastRetrieval,
CreationTime: curTime(),
InboundCAR: path,
}

err = p.deals.Begin(proposalNd.Cid(), deal)
err = p.deals.Begin(propCid, deal)
if err != nil {
return err
}
err = p.conns.AddStream(proposalNd.Cid(), s)
err = p.conns.AddStream(propCid, s)
if err != nil {
return err
}
return p.deals.Send(proposalNd.Cid(), storagemarket.ProviderEventOpen)
return p.deals.Send(propCid, storagemarket.ProviderEventOpen)
}

// Stop terminates processing of deals on a StorageProvider
Expand Down
9 changes: 7 additions & 2 deletions storagemarket/impl/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,17 @@ func TestHandleDealStream(t *testing.T) {

var responseWriteCount int
s := shared_testutil.NewTestStorageDealStream(shared_testutil.TestStorageDealStreamParams{
ProposalReader: func() (network.Proposal, error) {
ProposalReader: func() (network.Proposal, cid.Cid, error) {
propNd, err := cborutil.AsIpld(proposal)
if err != nil {
return network.Proposal{}, cid.Undef, err
}

return network.Proposal{
DealProposal: proposal,
Piece: dataRef,
FastRetrieval: false,
}, nil
}, propNd.Cid(), nil
},
ResponseWriter: func(response network.SignedResponse, resigningFunc network.ResigningFunc) error {
responseWriteCount += 1
Expand Down
72 changes: 39 additions & 33 deletions storagemarket/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,42 +219,13 @@ func MigrateMinerDeal0To1(oldCd *MinerDeal0) (*MinerDeal1, error) {

// MigrateMinerDeal1To2 migrates a miner deal label to the new format
func MigrateMinerDeal1To2(oldCd *MinerDeal1) (*storagemarket.MinerDeal, error) {
oldLabel := oldCd.Proposal.Label

var err error
var newLabel market.DealLabel
if utf8.ValidString(oldLabel) {
newLabel, err = market.NewLabelFromString(oldLabel)
if err != nil {
return nil, fmt.Errorf("migrating deal label to DealLabel (string) for deal with proposal cid %s: %w", oldCd.ProposalCid, err)
}
} else {
newLabel, err = market.NewLabelFromBytes([]byte(oldLabel))
if err != nil {
return nil, fmt.Errorf("migrating deal label to DealLabel (byte) for deal with proposal cid %s: %w", oldCd.ProposalCid, err)
}
clientDealProp, err := MigrateClientDealProposal0To1(oldCd.ClientDealProposal)
if err != nil {
return nil, fmt.Errorf("migrating deal with proposal cid %s: %w", oldCd.ProposalCid, err)
}

return &storagemarket.MinerDeal{
ClientDealProposal: storagemarket.ClientDealProposal{
ClientSignature: crypto.Signature{
Type: crypto.SigType(oldCd.ClientDealProposal.ClientSignature.Type),
Data: oldCd.ClientDealProposal.ClientSignature.Data,
},
Proposal: market.DealProposal{
PieceCID: oldCd.ClientDealProposal.Proposal.PieceCID,
PieceSize: oldCd.ClientDealProposal.Proposal.PieceSize,
VerifiedDeal: oldCd.ClientDealProposal.Proposal.VerifiedDeal,
Client: oldCd.ClientDealProposal.Proposal.Client,
Provider: oldCd.ClientDealProposal.Proposal.Provider,
Label: newLabel,
StartEpoch: oldCd.ClientDealProposal.Proposal.StartEpoch,
EndEpoch: oldCd.ClientDealProposal.Proposal.EndEpoch,
StoragePricePerEpoch: oldCd.ClientDealProposal.Proposal.StoragePricePerEpoch,
ProviderCollateral: oldCd.ClientDealProposal.Proposal.ProviderCollateral,
ClientCollateral: oldCd.ClientDealProposal.Proposal.ClientCollateral,
},
},
ClientDealProposal: *clientDealProp,
ProposalCid: oldCd.ProposalCid,
AddFundsCid: oldCd.AddFundsCid,
PublishCid: oldCd.PublishCid,
Expand All @@ -274,6 +245,41 @@ func MigrateMinerDeal1To2(oldCd *MinerDeal1) (*storagemarket.MinerDeal, error) {
}, nil
}

func MigrateClientDealProposal0To1(prop marketOld.ClientDealProposal) (*storagemarket.ClientDealProposal, error) {
oldLabel := prop.Proposal.Label

var err error
var newLabel market.DealLabel
if utf8.ValidString(oldLabel) {
newLabel, err = market.NewLabelFromString(oldLabel)
if err != nil {
return nil, fmt.Errorf("migrating deal label to DealLabel (string): %w", err)
}
} else {
newLabel, err = market.NewLabelFromBytes([]byte(oldLabel))
if err != nil {
return nil, fmt.Errorf("migrating deal label to DealLabel (byte): %w", err)
}
}

return &storagemarket.ClientDealProposal{
ClientSignature: prop.ClientSignature,
Proposal: market.DealProposal{
PieceCID: prop.Proposal.PieceCID,
PieceSize: prop.Proposal.PieceSize,
VerifiedDeal: prop.Proposal.VerifiedDeal,
Client: prop.Proposal.Client,
Provider: prop.Proposal.Provider,
Label: newLabel,
StartEpoch: prop.Proposal.StartEpoch,
EndEpoch: prop.Proposal.EndEpoch,
StoragePricePerEpoch: prop.Proposal.StoragePricePerEpoch,
ProviderCollateral: prop.Proposal.ProviderCollateral,
ClientCollateral: prop.Proposal.ClientCollateral,
},
}, nil
}

// MigrateStorageAsk0To1 migrates a tuple encoded storage ask to a map encoded storage ask
func MigrateStorageAsk0To1(oldSa *StorageAsk0) *storagemarket.StorageAsk {
return &storagemarket.StorageAsk{
Expand Down
9 changes: 8 additions & 1 deletion storagemarket/migrations/migrations_mapenc_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ import (
// generate directive in a separate file. So we define CBOR map-encoded types
// in this file

//go:generate cbor-gen-for --map-encoding MinerDeal1
//go:generate cbor-gen-for --map-encoding Proposal1 MinerDeal1

// Proposal1 is version 1 of Proposal (used by deal proposal protocol v1.1.0)
type Proposal1 struct {
DealProposal *marketOld.ClientDealProposal
Piece *storagemarket.DataRef
FastRetrieval bool
}

// MinerDeal1 is version 1 of MinerDeal
type MinerDeal1 struct {
Expand Down
162 changes: 162 additions & 0 deletions storagemarket/migrations/migrations_mapenc_types_cbor_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit fd8afb8

Please sign in to comment.