Skip to content

Commit 0b32d26

Browse files
committed
Improve error handling around POOL account intent operations
1 parent 06c3916 commit 0b32d26

File tree

4 files changed

+38
-24
lines changed

4 files changed

+38
-24
lines changed

pkg/code/data/account/postgres/model.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ func equivalentModels(obj1, obj2 *model) bool {
393393
return false
394394
}
395395

396+
if obj1.MintAccount != obj2.MintAccount {
397+
return false
398+
}
399+
396400
if obj1.Index != obj2.Index {
397401
return false
398402
}

pkg/code/server/transaction/errors.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ const (
2323
var (
2424
ErrTimedOutReceivingRequest = errors.New("timed out receiving request")
2525

26-
ErrTooManyPayments = NewIntentDeniedError("too many payments")
27-
ErrTransactionLimitExceeded = NewIntentDeniedError("dollar value exceeds limit")
28-
ErrNotManagedByCode = NewIntentDeniedError("at least one account is no longer managed by code")
26+
ErrTooManyPayments = NewIntentDeniedError("too many payments")
27+
ErrTransactionLimitExceeded = NewIntentDeniedError("dollar value exceeds limit")
28+
ErrSourceNotManagedByCode = NewIntentDeniedError("at least one source account is no longer managed by code")
29+
ErrDestinationNotManagedByCode = NewIntentDeniedError("a destination account is no longer managed by code")
2930

3031
ErrInvalidSignature = errors.New("invalid signature provided")
3132
ErrMissingSignature = errors.New("at least one signature is missing")

pkg/code/server/transaction/intent_handler.go

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -596,8 +596,19 @@ func (h *SendPublicPaymentIntentHandler) validateActions(
596596
}
597597

598598
// Code->Code public ayments can only be made to primary or pool accounts
599+
// that are open and managed by Code
599600
switch h.cachedDestinationAccountInfoRecord.AccountType {
600601
case commonpb.AccountType_PRIMARY, commonpb.AccountType_POOL:
602+
timelockRecord, err := h.data.GetTimelockByVault(ctx, destination.PublicKey().ToBase58())
603+
if err != nil {
604+
return err
605+
}
606+
if !common.IsManagedByCode(ctx, timelockRecord) {
607+
if timelockRecord.IsClosed() {
608+
return NewStaleStateError("destination account has been closed")
609+
}
610+
return ErrDestinationNotManagedByCode
611+
}
601612
default:
602613
return NewIntentValidationError("destination account must be a PRIMARY or POOL account")
603614
}
@@ -1381,7 +1392,7 @@ func validateAllUserAccountsManagedByCode(ctx context.Context, initiatorAccounts
13811392
// Try to unlock *ANY* latest account, and you're done
13821393
for _, accountRecords := range initiatorAccounts {
13831394
if !accountRecords.IsManagedByCode(ctx) {
1384-
return ErrNotManagedByCode
1395+
return ErrSourceNotManagedByCode
13851396
}
13861397
}
13871398

@@ -1683,15 +1694,14 @@ func validateClaimedGiftCard(ctx context.Context, data code_data.Provider, giftC
16831694
return err
16841695
}
16851696

1686-
isManagedByCode := common.IsManagedByCode(ctx, timelockRecord)
1687-
if !isManagedByCode {
1697+
if !common.IsManagedByCode(ctx, timelockRecord) {
16881698
if timelockRecord.IsClosed() {
16891699
// Better error messaging, since we know we'll never reopen the account
16901700
// and the balance is guaranteed to be claimed (not necessarily through
16911701
// Code server though).
16921702
return NewStaleStateError("gift card balance has already been claimed")
16931703
}
1694-
return ErrNotManagedByCode
1704+
return ErrSourceNotManagedByCode
16951705
}
16961706

16971707
//
@@ -1732,33 +1742,32 @@ func validateDistributedPool(ctx context.Context, data code_data.Provider, poolV
17321742
}
17331743

17341744
//
1735-
// Part 2: Is the full amount being distributed?
1745+
// Part 2: Is the pool account managed by Code?
17361746
//
17371747

1738-
poolBalance, err := balance.CalculateFromCache(ctx, data, poolVaultAccount)
1748+
timelockRecord, err := data.GetTimelockByVault(ctx, poolVaultAccount.PublicKey().ToBase58())
17391749
if err != nil {
17401750
return err
1741-
} else if poolBalance == 0 {
1742-
return NewStaleStateError("pool balance has already been distributed")
1743-
} else if distributedAmount != poolBalance {
1744-
return NewIntentValidationErrorf("must distribute entire pool balance of %d quarks", poolBalance)
1751+
}
1752+
1753+
if !common.IsManagedByCode(ctx, timelockRecord) {
1754+
if timelockRecord.IsClosed() {
1755+
return NewStaleStateError("pool balance has already been distributed")
1756+
}
1757+
return ErrSourceNotManagedByCode
17451758
}
17461759

17471760
//
1748-
// Part 3: Is the pool account managed by Code?
1761+
// Part 3: Is the full amount being distributed?
17491762
//
17501763

1751-
timelockRecord, err := data.GetTimelockByVault(ctx, poolVaultAccount.PublicKey().ToBase58())
1764+
poolBalance, err := balance.CalculateFromCache(ctx, data, poolVaultAccount)
17521765
if err != nil {
17531766
return err
1754-
}
1755-
1756-
isManagedByCode := common.IsManagedByCode(ctx, timelockRecord)
1757-
if !isManagedByCode {
1758-
if timelockRecord.IsClosed() {
1759-
return NewStaleStateError("pool balance has already been distributed")
1760-
}
1761-
return ErrNotManagedByCode
1767+
} else if poolBalance == 0 {
1768+
return NewStaleStateError("pool balance has already been distributed")
1769+
} else if distributedAmount != poolBalance {
1770+
return NewIntentValidationErrorf("must distribute entire pool balance of %d quarks", poolBalance)
17621771
}
17631772

17641773
return nil

pkg/code/server/transaction/local_simulation.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ func LocalSimulation(ctx context.Context, data code_data.Provider, actions []*tr
285285
if len(tokenAccountsToFetchBalance) > 0 {
286286
prefetchedBalances, err = balance.BatchCalculateFromCacheWithTokenAccounts(ctx, data, tokenAccountsToFetchBalance...)
287287
if err == balance.ErrNotManagedByCode {
288-
return nil, ErrNotManagedByCode
288+
return nil, ErrSourceNotManagedByCode
289289
} else if err != nil {
290290
return nil, err
291291
}

0 commit comments

Comments
 (0)