Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pi: Make billing status changes batched. #1535

Merged
merged 5 commits into from
Oct 10, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 26 additions & 24 deletions politeiad/client/pi.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package client
import (
"context"
"encoding/json"
"fmt"

pdv2 "github.com/decred/politeia/politeiad/api/v2"
"github.com/decred/politeia/politeiad/plugins/pi"
Expand Down Expand Up @@ -49,9 +48,9 @@ func (c *Client) PiSetBillingStatus(ctx context.Context, sbs pi.SetBillingStatus
func (c *Client) PiSummaries(ctx context.Context, tokens []string) (map[string]pi.SummaryReply, error) {
// Setup request
cmds := make([]pdv2.PluginCmd, 0, len(tokens))
for _, v := range tokens {
for _, t := range tokens {
cmds = append(cmds, pdv2.PluginCmd{
Token: v,
Token: t,
ID: pi.PluginID,
Command: pi.CmdSummary,
Payload: "",
Expand Down Expand Up @@ -84,40 +83,43 @@ func (c *Client) PiSummaries(ctx context.Context, tokens []string) (map[string]p
return ssr, nil
}

// PiBillingStatusChanges sends the pi plugin BillingStatusChanges command
// to the politeiad v2 API.
func (c *Client) PiBillingStatusChanges(ctx context.Context, token string) (*pi.BillingStatusChangesReply, error) {
// PiBillingStatusChanges sends a page of pi plugin BillingStatusChanges
// commands to the politeiad v2 API.
func (c *Client) PiBillingStatusChanges(ctx context.Context, tokens []string) (map[string]pi.BillingStatusChangesReply, error) {
// Setup request
cmds := []pdv2.PluginCmd{
{
Token: token,
cmds := make([]pdv2.PluginCmd, 0, len(tokens))
for _, t := range tokens {
cmds = append(cmds, pdv2.PluginCmd{
Token: t,
ID: pi.PluginID,
Command: pi.CmdBillingStatusChanges,
Payload: "",
},
})
}

// Send request
replies, err := c.PluginReads(ctx, cmds)
if err != nil {
return nil, err
}
if len(replies) == 0 {
return nil, fmt.Errorf("no replies found")
}
pcr := replies[0]
err = extractPluginCmdError(pcr)
if err != nil {
return nil, err
}

// Decode reply
var bscsr pi.BillingStatusChangesReply
err = json.Unmarshal([]byte(pcr.Payload), &bscsr)
if err != nil {
return nil, err
// Prepare reply
bscsr := make(map[string]pi.BillingStatusChangesReply, len(replies))
for _, v := range replies {
err = extractPluginCmdError(v)
if err != nil {
// Individual summary errors are ignored. The token will not
// be included in the returned summaries map.
continue
}
var bscr pi.BillingStatusChangesReply
err = json.Unmarshal([]byte(v.Payload), &bscr)
if err != nil {
return nil, err
}
bscsr[v.Token] = bscr
}

return &bscsr, nil
return bscsr, nil

}
43 changes: 27 additions & 16 deletions politeiawww/api/pi/v1/v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,20 @@ type Policy struct{}
// We have not updated the field names here to avoid introducing breaking
// changes.
type PolicyReply struct {
TextFileSizeMax uint32 `json:"textfilesizemax"` // In bytes
ImageFileCountMax uint32 `json:"imagefilecountmax"`
ImageFileSizeMax uint32 `json:"imagefilesizemax"` // In bytes
NameLengthMin uint32 `json:"namelengthmin"` // In characters
NameLengthMax uint32 `json:"namelengthmax"` // In characters
NameSupportedChars []string `json:"namesupportedchars"`
AmountMin uint64 `json:"amountmin"` // In cents
AmountMax uint64 `json:"amountmax"` // In cents
StartDateMin int64 `json:"startdatemin"` // Seconds from current time
EndDateMax int64 `json:"enddatemax"` // Seconds from current time
Domains []string `json:"domains"`
SummariesPageSize uint32 `json:"summariespagesize"`
BillingStatusChangesMax uint32 `json:"billingstatuschangesmax"`
TextFileSizeMax uint32 `json:"textfilesizemax"` // In bytes
ImageFileCountMax uint32 `json:"imagefilecountmax"`
ImageFileSizeMax uint32 `json:"imagefilesizemax"` // In bytes
NameLengthMin uint32 `json:"namelengthmin"` // In characters
NameLengthMax uint32 `json:"namelengthmax"` // In characters
NameSupportedChars []string `json:"namesupportedchars"`
AmountMin uint64 `json:"amountmin"` // In cents
AmountMax uint64 `json:"amountmax"` // In cents
StartDateMin int64 `json:"startdatemin"` // Seconds from current time
EndDateMax int64 `json:"enddatemax"` // Seconds from current time
Domains []string `json:"domains"`
SummariesPageSize uint32 `json:"summariespagesize"`
BillingStatusChangesPageSize uint32 `json:"billingstatuschangespagesize"`
BillingStatusChangesMax uint32 `json:"billingstatuschangesmax"`
}

const (
Expand Down Expand Up @@ -285,6 +286,10 @@ const (
// SummariesPageSize is the maximum number of proposal summaries that
// can be requested at any one time.
SummariesPageSize uint32 = 5

// BillingStatusChangesPageSize is the maximum number of billing status
// changes that can be requested at any one time.
BillingStatusChangesPageSize uint32 = 5
amass01 marked this conversation as resolved.
Show resolved Hide resolved
)

// Summaries requests the proposal summaries for the provided proposal tokens.
Expand All @@ -311,12 +316,18 @@ type Summary struct {
}

// BillingStatusChanges requests the billing status changes for the provided
// proposal token.
// proposal tokens.
type BillingStatusChanges struct {
Token string `json:"token"`
Tokens []string `json:"token"`
amass01 marked this conversation as resolved.
Show resolved Hide resolved
}

// BillingStatusChangesReply is the reply to the BillingStatusChanges command.
//
// BillingStatusChanges field contains the billing status changes for each
amass01 marked this conversation as resolved.
Show resolved Hide resolved
amass01 marked this conversation as resolved.
Show resolved Hide resolved
// of the provided tokens.
// The map will not contain an entry for any tokens that did not correspond
// to an actual proposal. It is the callers responsibility to ensure that
// the billing status changes are returned for all provided tokens.
type BillingStatusChangesReply struct {
BillingStatusChanges []BillingStatusChange `json:"billingstatuschanges"`
BillingStatusChanges map[string][]BillingStatusChange `json:"billingstatuschanges"`
}
22 changes: 13 additions & 9 deletions politeiawww/cmd/pictl/cmdproposalbillingstatuschanges.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
// proposal.
type cmdProposalBillingStatusChanges struct {
amass01 marked this conversation as resolved.
Show resolved Hide resolved
Args struct {
Token string `positional-arg-name:"token" required:"true"`
Tokens []string `positional-arg-name:"token" required:"true"`
amass01 marked this conversation as resolved.
Show resolved Hide resolved
} `positional-args:"true"`
}

Expand All @@ -36,7 +36,7 @@ func (c *cmdProposalBillingStatusChanges) Execute(args []string) error {

// Setup request
bscs := piv1.BillingStatusChanges{
Token: c.Args.Token,
Tokens: c.Args.Tokens,
}

// Send request
Expand All @@ -45,20 +45,24 @@ func (c *cmdProposalBillingStatusChanges) Execute(args []string) error {
return err
}

// Print billing status changes
for _, bsc := range bscsr.BillingStatusChanges {
printBillingStatusChange(bsc)
printf("-----\n")
// Print billing status changes for all tokens
for t, bscs := range bscsr.BillingStatusChanges {
printf("Billing Status Changes of %v\n", t)
amass01 marked this conversation as resolved.
Show resolved Hide resolved
for _, bsc := range bscs {
printBillingStatusChange(bsc)
printf("-----\n")
}
printf("\n")
}

return nil
}

// proposalBillingStatusChangesHelpMsg is printed to stdout by the help command.
const proposalBillingStatusChangesHelpMsg = `proposalbillingstatuschanges "token"
const proposalBillingStatusChangesHelpMsg = `proposalbillingstatuschanges "tokens..."

Return the billing status changes of a proposal.
Return the billing status changes for a page of propsoals.

Arguments:
1. token (string, required) Proposal censorship token
1. tokens (string, required) Proposal censorship tokens
`
27 changes: 14 additions & 13 deletions politeiawww/legacy/pi/pi.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,19 +274,20 @@ func New(cfg *config.Config, pdc *pdclient.Client, udb user.Database, m mail.Mai
events: e,
mail: m,
policy: &v1.PolicyReply{
TextFileSizeMax: textFileSizeMax,
ImageFileCountMax: imageFileCountMax,
ImageFileSizeMax: imageFileSizeMax,
NameLengthMin: titleLengthMin,
NameLengthMax: titleLengthMax,
NameSupportedChars: titleSupportedChars,
AmountMin: amountMin,
AmountMax: amountMax,
StartDateMin: startDateMin,
EndDateMax: endDateMax,
Domains: domains,
SummariesPageSize: v1.SummariesPageSize,
BillingStatusChangesMax: billingStatusChangesMax,
TextFileSizeMax: textFileSizeMax,
ImageFileCountMax: imageFileCountMax,
ImageFileSizeMax: imageFileSizeMax,
NameLengthMin: titleLengthMin,
NameLengthMax: titleLengthMax,
NameSupportedChars: titleSupportedChars,
AmountMin: amountMin,
AmountMax: amountMax,
StartDateMin: startDateMin,
EndDateMax: endDateMax,
Domains: domains,
SummariesPageSize: v1.SummariesPageSize,
BillingStatusChangesPageSize: v1.BillingStatusChangesPageSize,
BillingStatusChangesMax: billingStatusChangesMax,
},
}

Expand Down
31 changes: 23 additions & 8 deletions politeiawww/legacy/pi/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,38 @@ func (p *Pi) processSetBillingStatus(ctx context.Context, sbs v1.SetBillingStatu

// processBillingStatusChanges processes a pi v1 billingstatuschanges request.
func (p *Pi) processBillingStatusChanges(ctx context.Context, bscs v1.BillingStatusChanges) (*v1.BillingStatusChangesReply, error) {
log.Tracef("processBillingStatusChanges: %v", bscs.Token)
log.Tracef("processBillingStatusChanges: %v", bscs.Tokens)

pbscsr, err := p.politeiad.PiBillingStatusChanges(ctx, bscs.Token)
// Verify request size
if len(bscs.Tokens) > int(v1.BillingStatusChangesPageSize) {
return nil, v1.UserErrorReply{
ErrorCode: v1.ErrorCodePageSizeExceeded,
ErrorContext: fmt.Sprintf("max page size is %v",
v1.BillingStatusChangesPageSize),
}
}

pbscsr, err := p.politeiad.PiBillingStatusChanges(ctx, bscs.Tokens)
amass01 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}

// Convert reply to API.
amass01 marked this conversation as resolved.
Show resolved Hide resolved
billingStatusChanges := make([]v1.BillingStatusChange, 0,
len(pbscsr.BillingStatusChanges))
for _, bsc := range pbscsr.BillingStatusChanges {
billingStatusChanges = append(billingStatusChanges,
convertBillingStatusChangeToAPI(bsc))
billingStatusChangesMap := make(map[string][]v1.BillingStatusChange,
len(pbscsr))
// For each token, convert slice of billing status changes.
for t, bscs := range pbscsr {
billingStatusChanges := make([]v1.BillingStatusChange, 0,
len(bscs.BillingStatusChanges))
for _, bsc := range bscs.BillingStatusChanges {
billingStatusChanges = append(billingStatusChanges,
convertBillingStatusChangeToAPI(bsc))
}
billingStatusChangesMap[t] = billingStatusChanges
}

return &v1.BillingStatusChangesReply{
BillingStatusChanges: billingStatusChanges,
BillingStatusChanges: billingStatusChangesMap,
}, nil
}

Expand Down