Skip to content

Commit 538bf5c

Browse files
authored
Fix poller optimizations when there are multiple fee payments (#68)
1 parent 2dd09a7 commit 538bf5c

File tree

2 files changed

+73
-26
lines changed

2 files changed

+73
-26
lines changed

pkg/code/async/sequencer/intent_handler.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,20 +112,20 @@ func (h *SendPrivatePaymentIntentHandler) maybeMarkTempOutgoingAccountActionsAsA
112112
// account and optional fee to Code, respectively, all coming from the temp
113113
// outgoing account.
114114
var paymentToDestinationAction *action.Record
115-
var feePaymentAction *action.Record
115+
var feePaymentActions []*action.Record
116116
for _, actionRecord := range actionsRecords {
117117
switch actionRecord.ActionType {
118118
case action.NoPrivacyWithdraw:
119119
paymentToDestinationAction = actionRecord
120120
case action.NoPrivacyTransfer:
121-
feePaymentAction = actionRecord
121+
feePaymentActions = append(feePaymentActions, actionRecord)
122122
}
123123
}
124124

125125
if paymentToDestinationAction == nil {
126126
return errors.New("payment to destination action not found")
127127
}
128-
if feePaymentAction == nil && intentRecord.SendPrivatePaymentMetadata.IsMicroPayment {
128+
if len(feePaymentActions) == 0 && intentRecord.SendPrivatePaymentMetadata.IsMicroPayment {
129129
return errors.New("fee payment action not found")
130130
}
131131

@@ -145,8 +145,8 @@ func (h *SendPrivatePaymentIntentHandler) maybeMarkTempOutgoingAccountActionsAsA
145145
paymentToDestinationFulfillment = fulfillmentRecords[0]
146146
}
147147

148-
var feePaymentFulfillment *fulfillment.Record
149-
if feePaymentAction != nil {
148+
var feePaymentFulfillments []*fulfillment.Record
149+
for _, feePaymentAction := range feePaymentActions {
150150
fulfillmentRecords, err := h.data.GetAllFulfillmentsByTypeAndAction(
151151
ctx,
152152
fulfillment.NoPrivacyTransferWithAuthority,
@@ -156,13 +156,13 @@ func (h *SendPrivatePaymentIntentHandler) maybeMarkTempOutgoingAccountActionsAsA
156156
if err != nil {
157157
return err
158158
} else if err == nil && fulfillmentRecords[0].DisableActiveScheduling {
159-
feePaymentFulfillment = fulfillmentRecords[0]
159+
feePaymentFulfillments = append(feePaymentFulfillments, fulfillmentRecords[0])
160160
}
161161
}
162162

163163
// Short circuit if there's nothing to update to avoid redundant intent
164164
// state checks spanning all actions.
165-
if paymentToDestinationFulfillment == nil && feePaymentFulfillment == nil {
165+
if paymentToDestinationFulfillment == nil && len(feePaymentFulfillments) == 0 {
166166
return nil
167167
}
168168

@@ -206,7 +206,7 @@ func (h *SendPrivatePaymentIntentHandler) maybeMarkTempOutgoingAccountActionsAsA
206206

207207
// Mark fulfillments as actively scheduled when at least all treasury payments
208208
// to the temp outgoing account are in flight.
209-
if feePaymentFulfillment != nil {
209+
for _, feePaymentFulfillment := range feePaymentFulfillments {
210210
err = markFulfillmentAsActivelyScheduled(ctx, h.data, feePaymentFulfillment)
211211
if err != nil {
212212
return err

pkg/code/async/sequencer/intent_handler_test.go

Lines changed: 65 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ import (
99
"github.com/stretchr/testify/assert"
1010
"github.com/stretchr/testify/require"
1111

12-
"github.com/code-payments/code-server/pkg/currency"
13-
"github.com/code-payments/code-server/pkg/kin"
14-
"github.com/code-payments/code-server/pkg/pointer"
15-
"github.com/code-payments/code-server/pkg/testutil"
1612
code_data "github.com/code-payments/code-server/pkg/code/data"
1713
"github.com/code-payments/code-server/pkg/code/data/action"
1814
"github.com/code-payments/code-server/pkg/code/data/fulfillment"
1915
"github.com/code-payments/code-server/pkg/code/data/intent"
16+
"github.com/code-payments/code-server/pkg/currency"
17+
"github.com/code-payments/code-server/pkg/kin"
18+
"github.com/code-payments/code-server/pkg/pointer"
19+
"github.com/code-payments/code-server/pkg/testutil"
2020
)
2121

2222
func TestOpenAccountsIntentHandler_RemainInStatePending(t *testing.T) {
@@ -69,22 +69,35 @@ func TestSendPrivatePaymentIntentHandler_RemainInStatePending(t *testing.T) {
6969
env := setupIntentHandlerTestEnv(t)
7070

7171
intentHandler := env.handlersByType[intent.SendPrivatePayment]
72-
intentRecord := env.createIntent(t, intent.SendPrivatePayment)
7372

74-
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord.IntentId))
75-
env.assertIntentState(t, intentRecord.IntentId, intent.StatePending)
73+
intentRecord1 := env.createIntent(t, intent.SendPrivatePayment)
74+
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord1.IntentId))
75+
env.assertIntentState(t, intentRecord1.IntentId, intent.StatePending)
7676

77-
env.confirmFirstActionOfType(t, intentRecord.IntentId, action.PrivateTransfer)
78-
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord.IntentId))
79-
env.assertIntentState(t, intentRecord.IntentId, intent.StatePending)
77+
env.confirmFirstActionOfType(t, intentRecord1.IntentId, action.PrivateTransfer)
78+
env.confirmAllActionsOfType(t, intentRecord1.IntentId, action.NoPrivacyTransfer)
79+
env.confirmFirstActionOfType(t, intentRecord1.IntentId, action.NoPrivacyWithdraw)
80+
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord1.IntentId))
81+
env.assertIntentState(t, intentRecord1.IntentId, intent.StatePending)
8082

81-
env.confirmFirstActionOfType(t, intentRecord.IntentId, action.NoPrivacyTransfer)
82-
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord.IntentId))
83-
env.assertIntentState(t, intentRecord.IntentId, intent.StatePending)
83+
intentRecord2 := env.createIntent(t, intent.SendPrivatePayment)
84+
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord2.IntentId))
85+
env.assertIntentState(t, intentRecord2.IntentId, intent.StatePending)
8486

85-
env.confirmFirstActionOfType(t, intentRecord.IntentId, action.NoPrivacyWithdraw)
86-
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord.IntentId))
87-
env.assertIntentState(t, intentRecord.IntentId, intent.StatePending)
87+
env.confirmAllActionsOfType(t, intentRecord2.IntentId, action.PrivateTransfer)
88+
env.confirmFirstActionOfType(t, intentRecord2.IntentId, action.NoPrivacyTransfer)
89+
env.confirmFirstActionOfType(t, intentRecord2.IntentId, action.NoPrivacyWithdraw)
90+
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord2.IntentId))
91+
env.assertIntentState(t, intentRecord2.IntentId, intent.StatePending)
92+
93+
intentRecord3 := env.createIntent(t, intent.SendPrivatePayment)
94+
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord2.IntentId))
95+
env.assertIntentState(t, intentRecord3.IntentId, intent.StatePending)
96+
97+
env.confirmAllActionsOfType(t, intentRecord3.IntentId, action.PrivateTransfer)
98+
env.confirmAllActionsOfType(t, intentRecord3.IntentId, action.NoPrivacyTransfer)
99+
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord3.IntentId))
100+
env.assertIntentState(t, intentRecord3.IntentId, intent.StatePending)
88101
}
89102

90103
func TestSendPrivatePaymentIntentHandler_TransitionToStateConfirmed(t *testing.T) {
@@ -114,25 +127,33 @@ func TestSendPrivatePaymentIntentHandler_SchedulerPollingOptimizations(t *testin
114127
env.assertIntentState(t, intentRecord1.IntentId, intent.StatePending)
115128
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 2, false)
116129
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 3, false)
130+
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 4, false)
131+
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 5, false)
117132

118133
env.scheduleAllFulfillmentsOfType(t, intentRecord1.IntentId, fulfillment.TransferWithCommitment)
119134
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord1.IntentId))
120135
env.assertIntentState(t, intentRecord1.IntentId, intent.StatePending)
121136
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 2, true)
122137
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 3, true)
138+
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 4, true)
139+
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 5, true)
123140

124141
intentRecord2 := env.createIntent(t, intent.SendPrivatePayment)
125142

126143
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord2.IntentId))
127144
env.assertIntentState(t, intentRecord2.IntentId, intent.StatePending)
128145
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 2, false)
129146
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 3, false)
147+
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 4, false)
148+
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 5, false)
130149

131150
env.confirmAllFulfillmentsOfType(t, intentRecord2.IntentId, fulfillment.TransferWithCommitment)
132151
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord2.IntentId))
133152
env.assertIntentState(t, intentRecord2.IntentId, intent.StatePending)
134153
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 2, true)
135154
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 3, true)
155+
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 4, true)
156+
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 5, true)
136157
}
137158

138159
func TestSendPrivatePaymentIntentHandler_TransitionToStateFailed(t *testing.T) {
@@ -523,6 +544,32 @@ func (e *intentHandlerTestEnv) createIntent(t *testing.T, intentType intent.Type
523544
IntentType: intentType,
524545

525546
ActionId: 3,
547+
ActionType: action.NoPrivacyTransfer,
548+
549+
Source: tempOutgoing,
550+
Destination: pointer.String(testutil.NewRandomAccount(t).PublicKey().ToBase58()),
551+
Quantity: &feeAmount,
552+
553+
State: action.StatePending,
554+
},
555+
&action.Record{
556+
Intent: intentRecord.IntentId,
557+
IntentType: intentType,
558+
559+
ActionId: 4,
560+
ActionType: action.NoPrivacyTransfer,
561+
562+
Source: tempOutgoing,
563+
Destination: pointer.String(testutil.NewRandomAccount(t).PublicKey().ToBase58()),
564+
Quantity: &feeAmount,
565+
566+
State: action.StatePending,
567+
},
568+
&action.Record{
569+
Intent: intentRecord.IntentId,
570+
IntentType: intentType,
571+
572+
ActionId: 5,
526573
ActionType: action.NoPrivacyWithdraw,
527574

528575
Source: tempOutgoing,
@@ -535,7 +582,7 @@ func (e *intentHandlerTestEnv) createIntent(t *testing.T, intentType intent.Type
535582
Intent: intentRecord.IntentId,
536583
IntentType: intentType,
537584

538-
ActionId: 4,
585+
ActionId: 6,
539586
ActionType: action.OpenAccount,
540587

541588
Source: newTempOutgoing,
@@ -546,7 +593,7 @@ func (e *intentHandlerTestEnv) createIntent(t *testing.T, intentType intent.Type
546593
Intent: intentRecord.IntentId,
547594
IntentType: intentType,
548595

549-
ActionId: 5,
596+
ActionId: 7,
550597
ActionType: action.CloseDormantAccount,
551598

552599
Source: newTempOutgoing,

0 commit comments

Comments
 (0)