Skip to content

Commit b01176d

Browse files
committed
Add is_string column to market_deal_proposal model (#1015)
* chore: add is_string column to market_deal_proposal model
1 parent 7fc5900 commit b01176d

File tree

3 files changed

+71
-55
lines changed

3 files changed

+71
-55
lines changed

model/actors/market/dealproposal.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,12 @@ type MarketDealProposal struct {
4646

4747
// Deal is with a verified provider.
4848
IsVerified bool `pg:",notnull,use_zero"`
49-
// An arbitrary client chosen label to apply to the deal.
49+
// An arbitrary client chosen label to apply to the deal. The value is base64 encoded before persisting.
5050
Label string
51+
52+
// When true Label contains a valid UTF-8 string encoded in base64. When false Label contains raw bytes encoded in base64.
53+
// Related to FIP: https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0027.md
54+
IsString bool
5155
}
5256

5357
func (dp *MarketDealProposal) Persist(ctx context.Context, s model.StorageBatch, version model.Version) error {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package v1
2+
3+
func init() {
4+
patches.Register(
5+
7,
6+
`
7+
ALTER TABLE {{ .SchemaName | default "public"}}.market_deal_proposals
8+
ADD COLUMN is_string BOOLEAN;
9+
10+
COMMENT ON COLUMN {{ .SchemaName | default "public"}}.market_deal_proposals.is_string IS 'When true Label contains a valid UTF-8 string encoded in base64. When false Label contains raw bytes encoded in base64. Required by FIP: 27';
11+
`,
12+
)
13+
}

tasks/actorstate/market/deal_proposal.go

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package market
22

33
import (
44
"context"
5+
"encoding/base64"
56
"fmt"
67

78
"github.com/filecoin-project/go-state-types/abi"
@@ -34,74 +35,71 @@ func (DealProposalExtractor) Extract(ctx context.Context, a actorstate.ActorInfo
3435
return nil, err
3536
}
3637

37-
currDealProposals, err := ec.CurrState.Proposals()
38-
if err != nil {
39-
return nil, fmt.Errorf("loading current market deal proposals: %w", err)
40-
}
41-
38+
var dealProposals []market.ProposalIDState
39+
// if this is genesis iterator actors current state.
4240
if ec.IsGenesis() {
43-
var out marketmodel.MarketDealProposals
41+
currDealProposals, err := ec.CurrState.Proposals()
42+
if err != nil {
43+
return nil, fmt.Errorf("loading current market deal proposals: %w", err)
44+
}
45+
4446
if err := currDealProposals.ForEach(func(id abi.DealID, dp market.DealProposal) error {
45-
var label string
46-
if dp.Label.IsString() {
47-
var err error
48-
label, err = dp.Label.ToString()
49-
if err != nil {
50-
return fmt.Errorf("creating deal proposal label string: %w", err)
51-
}
52-
} else {
53-
label = ""
54-
}
55-
out = append(out, &marketmodel.MarketDealProposal{
56-
Height: int64(ec.CurrTs.Height()),
57-
DealID: uint64(id),
58-
StateRoot: ec.CurrTs.ParentState().String(),
59-
PaddedPieceSize: uint64(dp.PieceSize),
60-
UnpaddedPieceSize: uint64(dp.PieceSize.Unpadded()),
61-
StartEpoch: int64(dp.StartEpoch),
62-
EndEpoch: int64(dp.EndEpoch),
63-
ClientID: dp.Client.String(),
64-
ProviderID: dp.Provider.String(),
65-
ClientCollateral: dp.ClientCollateral.String(),
66-
ProviderCollateral: dp.ProviderCollateral.String(),
67-
StoragePricePerEpoch: dp.StoragePricePerEpoch.String(),
68-
PieceCID: dp.PieceCID.String(),
69-
IsVerified: dp.VerifiedDeal,
70-
Label: SanitizeLabel(label),
47+
dealProposals = append(dealProposals, market.ProposalIDState{
48+
ID: id,
49+
Proposal: dp,
7150
})
7251
return nil
7352
}); err != nil {
74-
return nil, fmt.Errorf("walking current deal states: %w", err)
53+
return nil, err
54+
}
55+
} else {
56+
// else diff the actor against previous state and collect any additions that occurred.
57+
changed, err := ec.CurrState.ProposalsChanged(ec.PrevState)
58+
if err != nil {
59+
return nil, fmt.Errorf("checking for deal proposal changes: %w", err)
60+
}
61+
if !changed {
62+
return nil, nil
7563
}
76-
return out, nil
7764

78-
}
65+
changes, err := market.DiffDealProposals(ctx, ec.Store, ec.PrevState, ec.CurrState)
66+
if err != nil {
67+
return nil, fmt.Errorf("diffing deal proposals: %w", err)
68+
}
7969

80-
changed, err := ec.CurrState.ProposalsChanged(ec.PrevState)
81-
if err != nil {
82-
return nil, fmt.Errorf("checking for deal proposal changes: %w", err)
70+
for _, change := range changes.Added {
71+
dealProposals = append(dealProposals, market.ProposalIDState{
72+
ID: change.ID,
73+
Proposal: change.Proposal,
74+
})
75+
}
8376
}
8477

85-
if !changed {
86-
return nil, nil
87-
}
78+
out := make(marketmodel.MarketDealProposals, len(dealProposals))
79+
for idx, add := range dealProposals {
80+
var isString bool
81+
var base64Label string
82+
if add.Proposal.Label.IsString() {
83+
labelString, err := add.Proposal.Label.ToString()
84+
if err != nil {
85+
return nil, fmt.Errorf("deal proposal (ID: %d) label is not a string despite claiming it is (developer error?)", add.ID)
86+
}
8887

89-
changes, err := market.DiffDealProposals(ctx, ec.Store, ec.PrevState, ec.CurrState)
90-
if err != nil {
91-
return nil, fmt.Errorf("diffing deal states: %w", err)
92-
}
88+
isString = true
89+
base64Label = base64.StdEncoding.EncodeToString([]byte(SanitizeLabel(labelString)))
9390

94-
out := make(marketmodel.MarketDealProposals, len(changes.Added))
95-
for idx, add := range changes.Added {
96-
var label string
97-
if add.Proposal.Label.IsString() {
98-
var err error
99-
label, err = add.Proposal.Label.ToString()
91+
} else if add.Proposal.Label.IsBytes() {
92+
labelBytes, err := add.Proposal.Label.ToBytes()
10093
if err != nil {
101-
return nil, fmt.Errorf("creating deal proposal label string: %w", err)
94+
return nil, fmt.Errorf("deal proposal (ID: %d) label is not bytes despit claiming it is (developer error?)", add.ID)
10295
}
96+
97+
isString = false
98+
base64Label = base64.StdEncoding.EncodeToString(labelBytes)
99+
103100
} else {
104-
label = ""
101+
// TODO this should never happen, but if it does it indicates a logic.
102+
return nil, fmt.Errorf("deal proposal (ID: %d) label is neither bytes nor string (DEVELOPER ERROR)", add.ID)
105103
}
106104
out[idx] = &marketmodel.MarketDealProposal{
107105
Height: int64(ec.CurrTs.Height()),
@@ -118,7 +116,8 @@ func (DealProposalExtractor) Extract(ctx context.Context, a actorstate.ActorInfo
118116
StoragePricePerEpoch: add.Proposal.StoragePricePerEpoch.String(),
119117
PieceCID: add.Proposal.PieceCID.String(),
120118
IsVerified: add.Proposal.VerifiedDeal,
121-
Label: SanitizeLabel(label),
119+
Label: base64Label,
120+
IsString: isString,
122121
}
123122
}
124123
return out, nil

0 commit comments

Comments
 (0)