Skip to content

Fix poller optimizations when there are multiple fee payments #68

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

Merged
merged 1 commit into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
16 changes: 8 additions & 8 deletions pkg/code/async/sequencer/intent_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,20 +112,20 @@ func (h *SendPrivatePaymentIntentHandler) maybeMarkTempOutgoingAccountActionsAsA
// account and optional fee to Code, respectively, all coming from the temp
// outgoing account.
var paymentToDestinationAction *action.Record
var feePaymentAction *action.Record
var feePaymentActions []*action.Record
for _, actionRecord := range actionsRecords {
switch actionRecord.ActionType {
case action.NoPrivacyWithdraw:
paymentToDestinationAction = actionRecord
case action.NoPrivacyTransfer:
feePaymentAction = actionRecord
feePaymentActions = append(feePaymentActions, actionRecord)
}
}

if paymentToDestinationAction == nil {
return errors.New("payment to destination action not found")
}
if feePaymentAction == nil && intentRecord.SendPrivatePaymentMetadata.IsMicroPayment {
if len(feePaymentActions) == 0 && intentRecord.SendPrivatePaymentMetadata.IsMicroPayment {
return errors.New("fee payment action not found")
}

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

var feePaymentFulfillment *fulfillment.Record
if feePaymentAction != nil {
var feePaymentFulfillments []*fulfillment.Record
for _, feePaymentAction := range feePaymentActions {
fulfillmentRecords, err := h.data.GetAllFulfillmentsByTypeAndAction(
ctx,
fulfillment.NoPrivacyTransferWithAuthority,
Expand All @@ -156,13 +156,13 @@ func (h *SendPrivatePaymentIntentHandler) maybeMarkTempOutgoingAccountActionsAsA
if err != nil {
return err
} else if err == nil && fulfillmentRecords[0].DisableActiveScheduling {
feePaymentFulfillment = fulfillmentRecords[0]
feePaymentFulfillments = append(feePaymentFulfillments, fulfillmentRecords[0])
}
}

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

Expand Down Expand Up @@ -206,7 +206,7 @@ func (h *SendPrivatePaymentIntentHandler) maybeMarkTempOutgoingAccountActionsAsA

// Mark fulfillments as actively scheduled when at least all treasury payments
// to the temp outgoing account are in flight.
if feePaymentFulfillment != nil {
for _, feePaymentFulfillment := range feePaymentFulfillments {
err = markFulfillmentAsActivelyScheduled(ctx, h.data, feePaymentFulfillment)
if err != nil {
return err
Expand Down
83 changes: 65 additions & 18 deletions pkg/code/async/sequencer/intent_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/code-payments/code-server/pkg/currency"
"github.com/code-payments/code-server/pkg/kin"
"github.com/code-payments/code-server/pkg/pointer"
"github.com/code-payments/code-server/pkg/testutil"
code_data "github.com/code-payments/code-server/pkg/code/data"
"github.com/code-payments/code-server/pkg/code/data/action"
"github.com/code-payments/code-server/pkg/code/data/fulfillment"
"github.com/code-payments/code-server/pkg/code/data/intent"
"github.com/code-payments/code-server/pkg/currency"
"github.com/code-payments/code-server/pkg/kin"
"github.com/code-payments/code-server/pkg/pointer"
"github.com/code-payments/code-server/pkg/testutil"
)

func TestOpenAccountsIntentHandler_RemainInStatePending(t *testing.T) {
Expand Down Expand Up @@ -69,22 +69,35 @@ func TestSendPrivatePaymentIntentHandler_RemainInStatePending(t *testing.T) {
env := setupIntentHandlerTestEnv(t)

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

require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord.IntentId))
env.assertIntentState(t, intentRecord.IntentId, intent.StatePending)
intentRecord1 := env.createIntent(t, intent.SendPrivatePayment)
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord1.IntentId))
env.assertIntentState(t, intentRecord1.IntentId, intent.StatePending)

env.confirmFirstActionOfType(t, intentRecord.IntentId, action.PrivateTransfer)
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord.IntentId))
env.assertIntentState(t, intentRecord.IntentId, intent.StatePending)
env.confirmFirstActionOfType(t, intentRecord1.IntentId, action.PrivateTransfer)
env.confirmAllActionsOfType(t, intentRecord1.IntentId, action.NoPrivacyTransfer)
env.confirmFirstActionOfType(t, intentRecord1.IntentId, action.NoPrivacyWithdraw)
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord1.IntentId))
env.assertIntentState(t, intentRecord1.IntentId, intent.StatePending)

env.confirmFirstActionOfType(t, intentRecord.IntentId, action.NoPrivacyTransfer)
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord.IntentId))
env.assertIntentState(t, intentRecord.IntentId, intent.StatePending)
intentRecord2 := env.createIntent(t, intent.SendPrivatePayment)
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord2.IntentId))
env.assertIntentState(t, intentRecord2.IntentId, intent.StatePending)

env.confirmFirstActionOfType(t, intentRecord.IntentId, action.NoPrivacyWithdraw)
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord.IntentId))
env.assertIntentState(t, intentRecord.IntentId, intent.StatePending)
env.confirmAllActionsOfType(t, intentRecord2.IntentId, action.PrivateTransfer)
env.confirmFirstActionOfType(t, intentRecord2.IntentId, action.NoPrivacyTransfer)
env.confirmFirstActionOfType(t, intentRecord2.IntentId, action.NoPrivacyWithdraw)
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord2.IntentId))
env.assertIntentState(t, intentRecord2.IntentId, intent.StatePending)

intentRecord3 := env.createIntent(t, intent.SendPrivatePayment)
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord2.IntentId))
env.assertIntentState(t, intentRecord3.IntentId, intent.StatePending)

env.confirmAllActionsOfType(t, intentRecord3.IntentId, action.PrivateTransfer)
env.confirmAllActionsOfType(t, intentRecord3.IntentId, action.NoPrivacyTransfer)
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord3.IntentId))
env.assertIntentState(t, intentRecord3.IntentId, intent.StatePending)
}

func TestSendPrivatePaymentIntentHandler_TransitionToStateConfirmed(t *testing.T) {
Expand Down Expand Up @@ -114,25 +127,33 @@ func TestSendPrivatePaymentIntentHandler_SchedulerPollingOptimizations(t *testin
env.assertIntentState(t, intentRecord1.IntentId, intent.StatePending)
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 2, false)
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 3, false)
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 4, false)
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 5, false)

env.scheduleAllFulfillmentsOfType(t, intentRecord1.IntentId, fulfillment.TransferWithCommitment)
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord1.IntentId))
env.assertIntentState(t, intentRecord1.IntentId, intent.StatePending)
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 2, true)
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 3, true)
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 4, true)
env.assertSchedulerPollingState(t, intentRecord1.IntentId, 5, true)

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

require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord2.IntentId))
env.assertIntentState(t, intentRecord2.IntentId, intent.StatePending)
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 2, false)
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 3, false)
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 4, false)
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 5, false)

env.confirmAllFulfillmentsOfType(t, intentRecord2.IntentId, fulfillment.TransferWithCommitment)
require.NoError(t, intentHandler.OnActionUpdated(env.ctx, intentRecord2.IntentId))
env.assertIntentState(t, intentRecord2.IntentId, intent.StatePending)
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 2, true)
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 3, true)
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 4, true)
env.assertSchedulerPollingState(t, intentRecord2.IntentId, 5, true)
}

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

ActionId: 3,
ActionType: action.NoPrivacyTransfer,

Source: tempOutgoing,
Destination: pointer.String(testutil.NewRandomAccount(t).PublicKey().ToBase58()),
Quantity: &feeAmount,

State: action.StatePending,
},
&action.Record{
Intent: intentRecord.IntentId,
IntentType: intentType,

ActionId: 4,
ActionType: action.NoPrivacyTransfer,

Source: tempOutgoing,
Destination: pointer.String(testutil.NewRandomAccount(t).PublicKey().ToBase58()),
Quantity: &feeAmount,

State: action.StatePending,
},
&action.Record{
Intent: intentRecord.IntentId,
IntentType: intentType,

ActionId: 5,
ActionType: action.NoPrivacyWithdraw,

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

ActionId: 4,
ActionId: 6,
ActionType: action.OpenAccount,

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

ActionId: 5,
ActionId: 7,
ActionType: action.CloseDormantAccount,

Source: newTempOutgoing,
Expand Down