fix(wallet): do not return gas-only ETH entries of transfers table for

activities request

Closes #4618
This commit is contained in:
Ivan Belyakov 2024-01-24 14:00:08 +01:00 committed by IvanBelyakoff
parent dad2ec3f66
commit 7d1927396a
5 changed files with 119 additions and 20 deletions

View File

@ -1378,3 +1378,74 @@ func TestGetMultiTxDetails(t *testing.T) {
require.Equal(t, td.multiTx1Tr2.Hash, details.ChainDetails[1].Hash) require.Equal(t, td.multiTx1Tr2.Hash, details.ChainDetails[1].Hash)
require.Equal(t, td.multiTx1Tr2.Contract, *details.ChainDetails[1].Contract) require.Equal(t, td.multiTx1Tr2.Contract, *details.ChainDetails[1].Contract)
} }
func TestGetActivityEntriesSkipEthGasFeeOnlyTransfers(t *testing.T) {
deps, close := setupTestActivityDB(t)
defer close()
to := eth.Address{0x1}
from := eth.Address{0x2}
hash := eth.Hash{0x3}
blkNum := int64(1)
chainID := common.ChainID(1)
nonce := uint64(1)
// Insert 0-value gas-only ETH transfer as a result of token transfer's gas fee
transfer.InsertTestTransfer(t, deps.db, to, &transfer.TestTransfer{
TestTransaction: transfer.TestTransaction{
ChainID: chainID,
From: from,
Hash: hash,
BlkNumber: blkNum,
Nonce: nonce,
},
To: to,
Value: 0,
})
entries, err := getActivityEntries(context.Background(), deps, []eth.Address{to}, true, []common.ChainID{chainID}, Filter{}, 0, 10)
require.NoError(t, err)
require.Equal(t, 1, len(entries))
require.Equal(t, hash, entries[0].transaction.Hash)
// Insert token transfer
transfer.InsertTestTransferWithOptions(t, deps.db, to,
&transfer.TestTransfer{
TestTransaction: transfer.TestTransaction{
ChainID: chainID,
From: from,
Hash: hash,
BlkNumber: blkNum,
Nonce: nonce,
},
To: to,
Value: 1,
},
&transfer.TestTransferOptions{
TokenAddress: eth.Address{0x4},
},
)
// Gas-fee-only transfer should be removed, so we get only 1 transfer again
entries, err = getActivityEntries(context.Background(), deps, []eth.Address{to}, true, []common.ChainID{chainID}, Filter{}, 0, 10)
require.NoError(t, err)
require.Equal(t, 1, len(entries))
require.Equal(t, contractTypeFromDBType("erc20"), entries[0].transferType)
// Insert real 0-value ETH transfer
transfer.InsertTestTransfer(t, deps.db, to, &transfer.TestTransfer{
TestTransaction: transfer.TestTransaction{
ChainID: chainID,
From: from,
Hash: eth.Hash{0x5}, // another hash
BlkNumber: blkNum,
Nonce: nonce + 1, // another nonce
},
To: to,
Value: 0, // 0-value as well
})
entries, err = getActivityEntries(context.Background(), deps, []eth.Address{to}, true, []common.ChainID{chainID}, Filter{}, 0, 10)
require.NoError(t, err)
require.Equal(t, 2, len(entries))
}

View File

@ -157,6 +157,7 @@ layer2_networks(network_id) AS (
mint_methods(method_hash) AS ( mint_methods(method_hash) AS (
%s %s
) )
SELECT SELECT
transfers.hash AS transfer_hash, transfers.hash AS transfer_hash,
NULL AS pending_hash, NULL AS pending_hash,

View File

@ -90,8 +90,8 @@ func (b *BlockRangeSequentialDAO) upsertRange(chainID uint64, account common.Add
return err return err
} }
ethBlockRange := prepareUpdatedBlockRange(chainID, account, ethTokensBlockRange.eth, newBlockRange.eth) ethBlockRange := prepareUpdatedBlockRange(ethTokensBlockRange.eth, newBlockRange.eth)
tokensBlockRange := prepareUpdatedBlockRange(chainID, account, ethTokensBlockRange.tokens, newBlockRange.tokens) tokensBlockRange := prepareUpdatedBlockRange(ethTokensBlockRange.tokens, newBlockRange.tokens)
log.Debug("update eth and tokens blocks range", "account", account, "chainID", chainID, log.Debug("update eth and tokens blocks range", "account", account, "chainID", chainID,
"eth.start", ethBlockRange.Start, "eth.first", ethBlockRange.FirstKnown, "eth.last", ethBlockRange.LastKnown, "eth.start", ethBlockRange.Start, "eth.first", ethBlockRange.FirstKnown, "eth.last", ethBlockRange.LastKnown,
@ -117,7 +117,7 @@ func (b *BlockRangeSequentialDAO) upsertEthRange(chainID uint64, account common.
return err return err
} }
blockRange := prepareUpdatedBlockRange(chainID, account, ethTokensBlockRange.eth, newBlockRange) blockRange := prepareUpdatedBlockRange(ethTokensBlockRange.eth, newBlockRange)
log.Debug("update eth blocks range", "account", account, "chainID", chainID, log.Debug("update eth blocks range", "account", account, "chainID", chainID,
"start", blockRange.Start, "first", blockRange.FirstKnown, "last", blockRange.LastKnown, "old hash", ethTokensBlockRange.balanceCheckHash) "start", blockRange.Start, "first", blockRange.FirstKnown, "last", blockRange.LastKnown, "old hash", ethTokensBlockRange.balanceCheckHash)
@ -146,7 +146,7 @@ func (b *BlockRangeSequentialDAO) updateTokenRange(chainID uint64, account commo
return err return err
} }
blockRange := prepareUpdatedBlockRange(chainID, account, ethTokensBlockRange.tokens, newBlockRange) blockRange := prepareUpdatedBlockRange(ethTokensBlockRange.tokens, newBlockRange)
log.Debug("update tokens blocks range", "account", account, "chainID", chainID, log.Debug("update tokens blocks range", "account", account, "chainID", chainID,
"start", blockRange.Start, "first", blockRange.FirstKnown, "last", blockRange.LastKnown, "old hash", ethTokensBlockRange.balanceCheckHash) "start", blockRange.Start, "first", blockRange.FirstKnown, "last", blockRange.LastKnown, "old hash", ethTokensBlockRange.balanceCheckHash)
@ -162,7 +162,7 @@ func (b *BlockRangeSequentialDAO) updateTokenRange(chainID uint64, account commo
return err return err
} }
func prepareUpdatedBlockRange(chainID uint64, account common.Address, blockRange, newBlockRange *BlockRange) *BlockRange { func prepareUpdatedBlockRange(blockRange, newBlockRange *BlockRange) *BlockRange {
// Update existing range // Update existing range
if blockRange != nil { if blockRange != nil {
if newBlockRange != nil { if newBlockRange != nil {

View File

@ -296,7 +296,7 @@ func (c *transfersCommand) saveAndConfirmPending(allTransfers []Transfer, blockN
if resErr != nil { if resErr != nil {
return resErr return resErr
} }
notifyFunctions := make([]func(), 0) notifyFunctions := c.confirmPendingTransactions(tx, allTransfers)
defer func() { defer func() {
if resErr == nil { if resErr == nil {
commitErr := tx.Commit() commitErr := tx.Commit()
@ -314,6 +314,17 @@ func (c *transfersCommand) saveAndConfirmPending(allTransfers []Transfer, blockN
} }
}() }()
resErr = saveTransfersMarkBlocksLoaded(tx, c.chainClient.NetworkID(), c.address, allTransfers, []*big.Int{blockNum})
if resErr != nil {
log.Error("SaveTransfers error", "error", resErr)
}
return resErr
}
func (c *transfersCommand) confirmPendingTransactions(tx *sql.Tx, allTransfers []Transfer) (notifyFunctions []func()) {
notifyFunctions = make([]func(), 0)
// Confirm all pending transactions that are included in this block // Confirm all pending transactions that are included in this block
for i, tr := range allTransfers { for i, tr := range allTransfers {
chainID := w_common.ChainID(tr.NetworkID) chainID := w_common.ChainID(tr.NetworkID)
@ -351,13 +362,7 @@ func (c *transfersCommand) saveAndConfirmPending(allTransfers []Transfer, blockN
notifyFunctions = append(notifyFunctions, notify) notifyFunctions = append(notifyFunctions, notify)
} }
} }
return notifyFunctions
resErr = saveTransfersMarkBlocksLoaded(tx, c.chainClient.NetworkID(), c.address, allTransfers, []*big.Int{blockNum})
if resErr != nil {
log.Error("SaveTransfers error", "error", resErr)
}
return resErr
} }
// Mark all subTxs of a given Tx with the same multiTxID // Mark all subTxs of a given Tx with the same multiTxID
@ -542,7 +547,7 @@ func (c *loadTransfersCommand) Command() async.Command {
}.Run }.Run
} }
// This command always returs nil, even if there is an error in one of the commands. // This command always returns nil, even if there is an error in one of the commands.
// `transferCommand`s retry until maxError, but this command doesn't retry. // `transferCommand`s retry until maxError, but this command doesn't retry.
// In case some transfer is not loaded after max retries, it will be retried only after restart of the app. // In case some transfer is not loaded after max retries, it will be retried only after restart of the app.
// Currently there is no implementation to keep retrying until success. I think this should be implemented // Currently there is no implementation to keep retrying until success. I think this should be implemented

View File

@ -492,6 +492,28 @@ func updateOrInsertTransfersDBFields(creator statementCreator, transfers []trans
log.Error("can't save transfer", "b-hash", t.blockHash, "b-n", t.blockNumber, "a", t.address, "h", t.id) log.Error("can't save transfer", "b-hash", t.blockHash, "b-n", t.blockNumber, "a", t.address, "h", t.id)
return err return err
} }
err = removeGasOnlyEthTransfer(creator, t)
if err != nil {
log.Error("can't remove gas only eth transfer", "b-hash", t.blockHash, "b-n", t.blockNumber, "a", t.address, "h", t.id, "err", err)
// no return err, since it's not critical
}
}
return nil
}
func removeGasOnlyEthTransfer(creator statementCreator, t transferDBFields) error {
if t.transferType != w_common.EthTransfer {
query, err := creator.Prepare(`DELETE FROM transfers WHERE tx_hash = ? AND address = ? AND network_id = ?
AND account_nonce = ? AND type = 'eth' AND amount_padded128hex = '00000000000000000000000000000000'`)
if err != nil {
return err
}
_, err = query.Exec(t.txHash, t.address, t.chainID, t.txNonce)
if err != nil {
return err
}
} }
return nil return nil
} }