Skip to content

Commit 02eed8a

Browse files
author
Jeff Yanta
committed
Ensure Timelock accounts aren't unlocked when being opened
1 parent 9c097b0 commit 02eed8a

1 file changed

Lines changed: 43 additions & 4 deletions

File tree

pkg/code/server/grpc/transaction/v2/intent_handler.go

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"github.com/code-payments/code-server/pkg/kin"
3434
"github.com/code-payments/code-server/pkg/pointer"
3535
push_lib "github.com/code-payments/code-server/pkg/push"
36+
"github.com/code-payments/code-server/pkg/solana"
3637
)
3738

3839
var accountTypesToOpen = []commonpb.AccountType{
@@ -218,7 +219,7 @@ func (h *OpenAccountsIntentHandler) AllowCreation(ctx context.Context, intentRec
218219
// Part 4: Validate the individual actions
219220
//
220221

221-
err = h.validateActions(initiatiorOwnerAccount, actions)
222+
err = h.validateActions(ctx, initiatiorOwnerAccount, actions)
222223
if err != nil {
223224
return err
224225
}
@@ -239,7 +240,7 @@ func (h *OpenAccountsIntentHandler) AllowCreation(ctx context.Context, intentRec
239240
return validateFeePayments(ctx, h.data, intentRecord, simResult)
240241
}
241242

242-
func (h *OpenAccountsIntentHandler) validateActions(initiatiorOwnerAccount *common.Account, actions []*transactionpb.Action) error {
243+
func (h *OpenAccountsIntentHandler) validateActions(ctx context.Context, initiatiorOwnerAccount *common.Account, actions []*transactionpb.Action) error {
243244
expectedActionCount := len(accountTypesToOpen)
244245
if len(actions) != expectedActionCount {
245246
return newIntentValidationErrorf("expected %d total actions", expectedActionCount)
@@ -283,6 +284,10 @@ func (h *OpenAccountsIntentHandler) validateActions(initiatiorOwnerAccount *comm
283284
if !bytes.Equal(openAction.GetOpenAccount().Token.Value, expectedVaultAccount.PublicKey().ToBytes()) {
284285
return newActionValidationErrorf(openAction, "token must be %s", expectedVaultAccount.PublicKey().ToBase58())
285286
}
287+
288+
if err := validateTimelockUnlockStateDoesntExist(ctx, h.data, openAction.GetOpenAccount()); err != nil {
289+
return err
290+
}
286291
}
287292

288293
return nil
@@ -758,6 +763,8 @@ func (h *SendPrivatePaymentIntentHandler) validateActions(
758763
}
759764

760765
err = validateGiftCardAccountOpened(
766+
ctx,
767+
h.data,
761768
initiatorOwnerAccount,
762769
initiatorAccountsByType,
763770
destination,
@@ -2137,10 +2144,10 @@ func (h *EstablishRelationshipIntentHandler) AllowCreation(ctx context.Context,
21372144
// Part 8: Validate the individual actions
21382145
//
21392146

2140-
return h.validateActions(initiatiorOwnerAccount, actions)
2147+
return h.validateActions(ctx, initiatiorOwnerAccount, actions)
21412148
}
21422149

2143-
func (h *EstablishRelationshipIntentHandler) validateActions(initiatiorOwnerAccount *common.Account, actions []*transactionpb.Action) error {
2150+
func (h *EstablishRelationshipIntentHandler) validateActions(ctx context.Context, initiatiorOwnerAccount *common.Account, actions []*transactionpb.Action) error {
21442151
if len(actions) != 1 {
21452152
return newIntentValidationError("expected 1 action")
21462153
}
@@ -2166,6 +2173,10 @@ func (h *EstablishRelationshipIntentHandler) validateActions(initiatiorOwnerAcco
21662173
return newActionValidationErrorf(openAction, "authority cannot be %s", initiatiorOwnerAccount.PublicKey().ToBase58())
21672174
}
21682175

2176+
if err := validateTimelockUnlockStateDoesntExist(ctx, h.data, openAction.GetOpenAccount()); err != nil {
2177+
return err
2178+
}
2179+
21692180
return nil
21702181
}
21712182

@@ -2476,6 +2487,8 @@ func validateNextTemporaryAccountOpened(
24762487

24772488
// Assumes only one gift card account is opened per intent
24782489
func validateGiftCardAccountOpened(
2490+
ctx context.Context,
2491+
data code_data.Provider,
24792492
initiatorOwnerAccount *common.Account,
24802493
initiatorAccountsByType map[commonpb.AccountType][]*common.AccountRecords,
24812494
expectedGiftCardVault *common.Account,
@@ -2524,6 +2537,10 @@ func validateGiftCardAccountOpened(
25242537
return newActionValidationErrorf(openAction, "token must be %s", derivedVaultAccount.PublicKey().ToBase58())
25252538
}
25262539

2540+
if err := validateTimelockUnlockStateDoesntExist(ctx, data, openAction.GetOpenAccount()); err != nil {
2541+
return err
2542+
}
2543+
25272544
return nil
25282545
}
25292546

@@ -2861,6 +2878,28 @@ func validateTipDestination(ctx context.Context, data code_data.Provider, tipped
28612878
return nil
28622879
}
28632880

2881+
func validateTimelockUnlockStateDoesntExist(ctx context.Context, data code_data.Provider, openAction *transactionpb.OpenAccountAction) error {
2882+
authorityAccount, err := common.NewAccountFromProto(openAction.Authority)
2883+
if err != nil {
2884+
return err
2885+
}
2886+
2887+
timelockAccounts, err := authorityAccount.GetTimelockAccounts(common.CodeVmAccount, common.KinMintAccount)
2888+
if err != nil {
2889+
return err
2890+
}
2891+
2892+
_, err = data.GetBlockchainAccountInfo(ctx, timelockAccounts.Unlock.PublicKey().ToBase58(), solana.CommitmentFinalized)
2893+
switch err {
2894+
case nil:
2895+
return newIntentDeniedError("an account being opened has already initiated an unlock")
2896+
case solana.ErrNoAccountInfo:
2897+
return nil
2898+
default:
2899+
return err
2900+
}
2901+
}
2902+
28642903
func getExpectedTimelockVaultFromProtoAccount(authorityProto *commonpb.SolanaAccountId) (*common.Account, error) {
28652904
authorityAccount, err := common.NewAccountFromProto(authorityProto)
28662905
if err != nil {

0 commit comments

Comments
 (0)