From c5cd41fe370b2d1d55bc8d590ccc9fc18dd18cec Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Fri, 30 Aug 2024 13:25:25 +0300 Subject: [PATCH] Improve COA creation transaction to gracefully handle existing COA in storage --- services/requester/cadence/create_coa.cdc | 25 ++++++++++++++--------- services/requester/requester.go | 3 ++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/services/requester/cadence/create_coa.cdc b/services/requester/cadence/create_coa.cdc index b58cf371..443cb836 100644 --- a/services/requester/cadence/create_coa.cdc +++ b/services/requester/cadence/create_coa.cdc @@ -3,24 +3,29 @@ import FungibleToken import FlowToken transaction(amount: UFix64) { - let sentVault: @FlowToken.Vault let auth: auth(Storage) &Account prepare(signer: auth(Storage) &Account) { - let vaultRef = signer.storage.borrow( - from: /storage/flowTokenVault - ) ?? panic("Could not borrow reference to the owner's Vault!") - - self.sentVault <- vaultRef.withdraw(amount: amount) as! @FlowToken.Vault self.auth = signer } execute { + // If the COA is already created & saved, there's nothing to do, just return. + if let coa = self.auth.storage.borrow<&EVM.CadenceOwnedAccount>(from: /storage/evm) { + return + } + + let vaultRef = self.auth.storage.borrow( + from: /storage/flowTokenVault + ) ?? panic("Could not borrow reference to the owner's Vault!") + let vault <- vaultRef.withdraw(amount: amount) as! @FlowToken.Vault + let account <- EVM.createCadenceOwnedAccount() - log(account.address()) - account.deposit(from: <-self.sentVault) + account.deposit(from: <-vault) - log(account.balance()) - self.auth.storage.save<@EVM.CadenceOwnedAccount>(<-account, to: StoragePath(identifier: "evm")!) + self.auth.storage.save<@EVM.CadenceOwnedAccount>( + <-account, + to: /storage/evm + ) } } diff --git a/services/requester/requester.go b/services/requester/requester.go index 5db4aa80..c1fb125d 100644 --- a/services/requester/requester.go +++ b/services/requester/requester.go @@ -181,7 +181,6 @@ func NewEVM( // create COA on the account if config.CreateCOAResource { - // we ignore errors for now since creation of already existing COA resource will fail, which is fine for now tx, err := evm.buildTransaction( context.Background(), evm.replaceAddresses(createCOAScript), @@ -189,9 +188,11 @@ func NewEVM( ) if err != nil { logger.Warn().Err(err).Msg("COA resource auto-creation failure") + return nil, fmt.Errorf("COA resource auto-creation failure: %w", err) } if err := evm.client.SendTransaction(context.Background(), *tx); err != nil { logger.Warn().Err(err).Msg("failed to send COA resource auto-creation transaction") + return nil, fmt.Errorf("failed to send COA resource auto-creation transaction: %w", err) } }