fix(wallet): do not return gas-only ETH entries of transfers table for
activities request Closes #4618
This commit is contained in:
parent
dad2ec3f66
commit
7d1927396a
|
@ -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))
|
||||||
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue