diff --git a/services/wallet/api.go b/services/wallet/api.go index 54ccfe81ba2..8831556df20 100644 --- a/services/wallet/api.go +++ b/services/wallet/api.go @@ -107,56 +107,6 @@ type DerivedAddress struct { AlreadyCreated bool `json:"alreadyCreated"` } -// @deprecated -func (api *API) CheckRecentHistory(ctx context.Context, addresses []common.Address) error { - return api.s.transferController.CheckRecentHistory([]uint64{api.s.rpcClient.UpstreamChainID}, addresses) -} - -// @deprecated -func (api *API) CheckRecentHistoryForChainIDs(ctx context.Context, chainIDs []uint64, addresses []common.Address) error { - return api.s.transferController.CheckRecentHistory(chainIDs, addresses) -} - -func hexBigToBN(hexBig *hexutil.Big) *big.Int { - var bN *big.Int - if hexBig != nil { - bN = hexBig.ToInt() - } - return bN -} - -// @deprecated -// GetTransfersByAddress returns transfers for a single address -func (api *API) GetTransfersByAddress(ctx context.Context, address common.Address, toBlock, limit *hexutil.Big, fetchMore bool) ([]transfer.View, error) { - logutils.ZapLogger().Debug("[WalletAPI:: GetTransfersByAddress] get transfers for an address", zap.Stringer("address", address)) - var intLimit = int64(1) - if limit != nil { - intLimit = limit.ToInt().Int64() - } - return api.s.transferController.GetTransfersByAddress(ctx, api.s.rpcClient.UpstreamChainID, address, hexBigToBN(toBlock), intLimit, fetchMore) -} - -// @deprecated -// LoadTransferByHash loads transfer to the database -// Only used by status-mobile -func (api *API) LoadTransferByHash(ctx context.Context, address common.Address, hash common.Hash) error { - logutils.ZapLogger().Debug("[WalletAPI:: LoadTransferByHash] get transfer by hash", zap.Stringer("address", address), zap.Stringer("hash", hash)) - return api.s.transferController.LoadTransferByHash(ctx, api.s.rpcClient, address, hash) -} - -// @deprecated -func (api *API) GetTransfersByAddressAndChainID(ctx context.Context, chainID uint64, address common.Address, toBlock, limit *hexutil.Big, fetchMore bool) ([]transfer.View, error) { - logutils.ZapLogger().Debug("[WalletAPI:: GetTransfersByAddressAndChainIDs] get transfers for an address", zap.Stringer("address", address)) - return api.s.transferController.GetTransfersByAddress(ctx, chainID, address, hexBigToBN(toBlock), limit.ToInt().Int64(), fetchMore) -} - -// @deprecated -func (api *API) GetTransfersForIdentities(ctx context.Context, identities []transfer.TransactionIdentity) ([]transfer.View, error) { - logutils.ZapLogger().Debug("wallet.api.GetTransfersForIdentities", zap.Int("identities.len", len(identities))) - - return api.s.transferController.GetTransfersForIdentities(ctx, identities) -} - func (api *API) FetchDecodedTxData(ctx context.Context, data string) (*thirdparty.DataParsed, error) { logutils.ZapLogger().Debug("[Wallet: FetchDecodedTxData]") diff --git a/services/wallet/routeexecution/manager.go b/services/wallet/routeexecution/manager.go index fab5684c1b5..53bcfa8df2a 100644 --- a/services/wallet/routeexecution/manager.go +++ b/services/wallet/routeexecution/manager.go @@ -5,14 +5,10 @@ import ( "database/sql" "time" - "go.uber.org/zap" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" - "github.com/status-im/status-go/logutils" - status_common "github.com/status-im/status-go/common" statusErrors "github.com/status-im/status-go/errors" "github.com/status-im/status-go/services/wallet/requests" @@ -209,26 +205,5 @@ func (m *Manager) SendRouterTransactionsWithSignatures(ctx context.Context, send if tmpErr != nil { log.Error("Error storing route data", "error", tmpErr) } - - var ( - chainIDs []uint64 - addresses []common.Address - ) - for _, tx := range response.SentTransactions { - chainIDs = append(chainIDs, tx.FromChain) - addresses = append(addresses, common.Address(tx.FromAddress)) - go func(chainId uint64, txHash common.Hash) { - defer status_common.LogOnPanic() - tmpErr = m.transactionManager.WatchTransaction(context.Background(), chainId, txHash) - if tmpErr != nil { - logutils.ZapLogger().Error("Error watching transaction", zap.Error(tmpErr)) - return - } - }(tx.FromChain, common.Hash(tx.Hash)) - } - tmpErr = m.transferController.CheckRecentHistory(chainIDs, addresses) - if tmpErr != nil { - logutils.ZapLogger().Error("Error checking recent history", zap.Error(tmpErr)) - } }() } diff --git a/services/wallet/transfer/block_dao.go b/services/wallet/transfer/block_dao.go index 3c21746de21..692808b576e 100644 --- a/services/wallet/transfer/block_dao.go +++ b/services/wallet/transfer/block_dao.go @@ -22,97 +22,10 @@ type Block struct { Nonce *int64 } -type BlockView struct { - Address common.Address `json:"address"` - Number *big.Int `json:"blockNumber"` - Balance bigint.BigInt `json:"balance"` - Nonce *int64 `json:"nonce"` -} - -func blocksToViews(blocks map[common.Address]*Block) []BlockView { - blocksViews := []BlockView{} - for address, block := range blocks { - view := BlockView{ - Address: address, - Number: block.Number, - Balance: bigint.BigInt{Int: block.Balance}, - Nonce: block.Nonce, - } - blocksViews = append(blocksViews, view) - } - - return blocksViews -} - type BlockDAO struct { db *sql.DB } -// MergeBlocksRanges merge old blocks ranges if possible -func (b *BlockDAO) mergeBlocksRanges(chainIDs []uint64, accounts []common.Address) error { - for _, chainID := range chainIDs { - for _, account := range accounts { - err := b.mergeRanges(chainID, account) - if err != nil { - return err - } - } - } - return nil -} - -func (b *BlockDAO) mergeRanges(chainID uint64, account common.Address) (err error) { - var ( - tx *sql.Tx - ) - - ranges, err := b.getOldRanges(chainID, account) - if err != nil { - return err - } - - logutils.ZapLogger().Info("merge old ranges", - zap.Stringer("account", account), - zap.Uint64("network", chainID), - zap.Int("ranges", len(ranges)), - ) - - if len(ranges) <= 1 { - return nil - } - - tx, err = b.db.Begin() - if err != nil { - return err - } - - defer func() { - if err == nil { - err = tx.Commit() - return - } - _ = tx.Rollback() - }() - - newRanges, deletedRanges := getNewRanges(ranges) - - for _, rangeToDelete := range deletedRanges { - err = deleteRange(chainID, tx, account, rangeToDelete.from, rangeToDelete.to) - if err != nil { - return err - } - } - - for _, newRange := range newRanges { - err = insertRange(chainID, tx, account, newRange.from, newRange.to) - if err != nil { - return err - } - } - - return nil -} - func (b *BlockDAO) insertRange(chainID uint64, account common.Address, from, to, balance *big.Int, nonce uint64) error { logutils.ZapLogger().Debug( "insert blocks range", @@ -131,35 +44,6 @@ func (b *BlockDAO) insertRange(chainID uint64, account common.Address, from, to, return err } -func (b *BlockDAO) getOldRanges(chainID uint64, account common.Address) ([]*BlocksRange, error) { - query := `select blk_from, blk_to from blocks_ranges - where address = ? - and network_id = ? - order by blk_from` - - rows, err := b.db.Query(query, account, chainID) - if err != nil { - return nil, err - } - defer rows.Close() - ranges := []*BlocksRange{} - for rows.Next() { - from := &big.Int{} - to := &big.Int{} - err = rows.Scan((*bigint.SQLBigInt)(from), (*bigint.SQLBigInt)(to)) - if err != nil { - return nil, err - } - - ranges = append(ranges, &BlocksRange{ - from: from, - to: to, - }) - } - - return ranges, nil -} - // GetBlocksToLoadByAddress gets unloaded blocks for a given address. func (b *BlockDAO) GetBlocksToLoadByAddress(chainID uint64, address common.Address, limit int) (rst []*big.Int, err error) { query := `SELECT blk_number FROM blocks @@ -205,56 +89,6 @@ func (b *BlockDAO) GetLastBlockByAddress(chainID uint64, address common.Address, return nil, nil } -func (b *BlockDAO) GetFirstSavedBlock(chainID uint64, address common.Address) (rst *DBHeader, err error) { - query := `SELECT blk_number, blk_hash, loaded - FROM blocks - WHERE network_id = ? AND address = ? - ORDER BY blk_number LIMIT 1` - rows, err := b.db.Query(query, chainID, address) - if err != nil { - return - } - defer rows.Close() - - if rows.Next() { - header := &DBHeader{Hash: common.Hash{}, Number: new(big.Int)} - err = rows.Scan((*bigint.SQLBigInt)(header.Number), &header.Hash, &header.Loaded) - if err != nil { - return nil, err - } - - return header, nil - } - - return nil, nil -} - -func (b *BlockDAO) GetFirstKnownBlock(chainID uint64, address common.Address) (rst *big.Int, err error) { - query := `SELECT blk_from FROM blocks_ranges - WHERE address = ? - AND network_id = ? - ORDER BY blk_from - LIMIT 1` - - rows, err := b.db.Query(query, address, chainID) - if err != nil { - return - } - defer rows.Close() - - if rows.Next() { - block := &big.Int{} - err = rows.Scan((*bigint.SQLBigInt)(block)) - if err != nil { - return nil, err - } - - return block, nil - } - - return nil, nil -} - func (b *BlockDAO) GetLastKnownBlockByAddress(chainID uint64, address common.Address) (block *Block, err error) { query := `SELECT blk_to, balance, nonce FROM blocks_ranges WHERE address = ? @@ -285,43 +119,6 @@ func (b *BlockDAO) GetLastKnownBlockByAddress(chainID uint64, address common.Add return nil, nil } -func (b *BlockDAO) getLastKnownBlocks(chainID uint64, addresses []common.Address) (map[common.Address]*Block, error) { - result := map[common.Address]*Block{} - for _, address := range addresses { - block, error := b.GetLastKnownBlockByAddress(chainID, address) - if error != nil { - return nil, error - } - - if block != nil { - result[address] = block - } - } - - return result, nil -} - -// TODO Remove the method below, it is used in one place and duplicates getLastKnownBlocks method with slight unneeded change -func (b *BlockDAO) GetLastKnownBlockByAddresses(chainID uint64, addresses []common.Address) (map[common.Address]*Block, []common.Address, error) { - res := map[common.Address]*Block{} - accountsWithoutHistory := []common.Address{} - for _, address := range addresses { - block, err := b.GetLastKnownBlockByAddress(chainID, address) - if err != nil { - logutils.ZapLogger().Info("Can't get last block", zap.Error(err)) - return nil, nil, err - } - - if block != nil { - res[address] = block - } else { - accountsWithoutHistory = append(accountsWithoutHistory, address) - } - } - - return res, accountsWithoutHistory, nil -} - func getNewRanges(ranges []*BlocksRange) ([]*BlocksRange, []*BlocksRange) { initValue := big.NewInt(-1) prevFrom := big.NewInt(-1) @@ -369,27 +166,6 @@ func getNewRanges(ranges []*BlocksRange) ([]*BlocksRange, []*BlocksRange) { return newRanges, deletedRanges } -func deleteRange(chainID uint64, creator statementCreator, account common.Address, from *big.Int, to *big.Int) error { - logutils.ZapLogger().Info("delete blocks range", - zap.Stringer("account", account), - zap.Uint64("network", chainID), - zap.Stringer("from", from), - zap.Stringer("to", to), - ) - delete, err := creator.Prepare(`DELETE FROM blocks_ranges - WHERE address = ? - AND network_id = ? - AND blk_from = ? - AND blk_to = ?`) - if err != nil { - logutils.ZapLogger().Info("some error", zap.Error(err)) - return err - } - - _, err = delete.Exec(account, chainID, (*bigint.SQLBigInt)(from), (*bigint.SQLBigInt)(to)) - return err -} - func deleteAllRanges(creator statementCreator, account common.Address) error { delete, err := creator.Prepare(`DELETE FROM blocks_ranges WHERE address = ?`) if err != nil { @@ -399,19 +175,3 @@ func deleteAllRanges(creator statementCreator, account common.Address) error { _, err = delete.Exec(account) return err } - -func insertRange(chainID uint64, creator statementCreator, account common.Address, from *big.Int, to *big.Int) error { - logutils.ZapLogger().Info("insert blocks range", - zap.Stringer("account", account), - zap.Uint64("network", chainID), - zap.Stringer("from", from), - zap.Stringer("to", to), - ) - insert, err := creator.Prepare("INSERT INTO blocks_ranges (network_id, address, blk_from, blk_to) VALUES (?, ?, ?, ?)") - if err != nil { - return err - } - - _, err = insert.Exec(chainID, account, (*bigint.SQLBigInt)(from), (*bigint.SQLBigInt)(to)) - return err -} diff --git a/services/wallet/transfer/commands_sequential.go b/services/wallet/transfer/commands_sequential.go index 19961aa74a8..c6b128e0a44 100644 --- a/services/wallet/transfer/commands_sequential.go +++ b/services/wallet/transfer/commands_sequential.go @@ -1484,7 +1484,7 @@ func (c *loadBlocksAndTransfersCommand) areAllTransfersLoaded(account common.Add if allBlocksLoaded { headers, err := c.blockDAO.GetBlocksToLoadByAddress(c.chainClient.NetworkID(), account, 1) if err != nil { - logutils.ZapLogger().Error("loadBlocksAndTransfersCommand GetFirstSavedBlock", zap.Error(err)) + logutils.ZapLogger().Error("loadBlocksAndTransfersCommand GetBlocksToLoadByAddress", zap.Error(err)) return false, err } diff --git a/services/wallet/transfer/controller.go b/services/wallet/transfer/controller.go index f07f16706a2..4041ea178cd 100644 --- a/services/wallet/transfer/controller.go +++ b/services/wallet/transfer/controller.go @@ -1,16 +1,12 @@ package transfer import ( - "context" "database/sql" - "fmt" - "math/big" "go.uber.org/zap" "golang.org/x/exp/slices" // since 1.21, this is in the standard library "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" gocommon "github.com/status-im/status-go/common" "github.com/status-im/status-go/logutils" @@ -80,64 +76,6 @@ func (c *Controller) Stop() { } } -func sameChains(chainIDs1 []uint64, chainIDs2 []uint64) bool { - if len(chainIDs1) != len(chainIDs2) { - return false - } - - for _, chainID := range chainIDs1 { - if !slices.Contains(chainIDs2, chainID) { - return false - } - } - - return true -} - -func (c *Controller) CheckRecentHistory(chainIDs []uint64, accounts []common.Address) error { - if len(accounts) == 0 { - return nil - } - - if len(chainIDs) == 0 { - return nil - } - - err := c.blockDAO.mergeBlocksRanges(chainIDs, accounts) - if err != nil { - return err - } - - chainClients, err := c.rpcClient.EthClients(chainIDs) - if err != nil { - return err - } - - if c.reactor != nil { - if !sameChains(chainIDs, c.reactor.chainIDs) { - err := c.reactor.restart(chainClients, accounts) - if err != nil { - return err - } - } - - return nil - } - - const omitHistory = true - c.reactor = NewReactor(c.db, c.blockDAO, c.blockRangesSeqDAO, c.accountsDB, c.TransferFeed, c.transactionManager, - c.pendingTxManager, c.tokenManager, c.balanceCacher, omitHistory, c.blockChainState) - - err = c.reactor.start(chainClients, accounts) - if err != nil { - return err - } - - c.startAccountWatcher(chainIDs) - - return nil -} - func (c *Controller) startAccountWatcher(chainIDs []uint64) { if c.accWatcher == nil { c.accWatcher = accountsevent.NewWatcher(c.accountsDB, c.accountFeed, func(changedAddresses []common.Address, eventType accountsevent.EventType, currentAddresses []common.Address) { @@ -174,76 +112,6 @@ func (c *Controller) onAccountsChanged(changedAddresses []common.Address, eventT } } -// Only used by status-mobile -func (c *Controller) LoadTransferByHash(ctx context.Context, rpcClient *rpc.Client, address common.Address, hash common.Hash) error { - chainClient, err := rpcClient.EthClient(rpcClient.UpstreamChainID) - if err != nil { - return err - } - - signer := types.LatestSignerForChainID(chainClient.ToBigInt()) - - transfer, err := getTransferByHash(ctx, chainClient, signer, address, hash) - if err != nil { - return err - } - - transfers := []Transfer{*transfer} - - err = c.db.InsertBlock(rpcClient.UpstreamChainID, address, transfer.BlockNumber, transfer.BlockHash) - if err != nil { - return err - } - - tx, err := c.db.client.BeginTx(ctx, nil) - if err != nil { - return err - } - - blocks := []*big.Int{transfer.BlockNumber} - err = saveTransfersMarkBlocksLoaded(tx, rpcClient.UpstreamChainID, address, transfers, blocks) - if err != nil { - rollErr := tx.Rollback() - if rollErr != nil { - return fmt.Errorf("failed to rollback transaction due to error: %v", err) - } - return err - } - - return nil -} - -func (c *Controller) GetTransfersByAddress(ctx context.Context, chainID uint64, address common.Address, toBlock *big.Int, - limit int64, fetchMore bool) ([]View, error) { - - rst, err := c.reactor.getTransfersByAddress(ctx, chainID, address, toBlock, limit) - if err != nil { - logutils.ZapLogger().Error("[WalletAPI:: GetTransfersByAddress] can't fetch transfers", zap.Error(err)) - return nil, err - } - - return castToTransferViews(rst), nil -} - -func (c *Controller) GetTransfersForIdentities(ctx context.Context, identities []TransactionIdentity) ([]View, error) { - rst, err := c.db.GetTransfersForIdentities(ctx, identities) - if err != nil { - logutils.ZapLogger().Error("[transfer.Controller.GetTransfersForIdentities] DB err", zap.Error(err)) - return nil, err - } - - return castToTransferViews(rst), nil -} - -func (c *Controller) GetCachedBalances(ctx context.Context, chainID uint64, addresses []common.Address) ([]BlockView, error) { - result, error := c.blockDAO.getLastKnownBlocks(chainID, addresses) - if error != nil { - return nil, error - } - - return blocksToViews(result), nil -} - func (c *Controller) cleanUpRemovedAccount(address common.Address) { // Transfers will be deleted by foreign key constraint by cascade err := deleteBlocks(c.db.client, address) diff --git a/services/wallet/transfer/database.go b/services/wallet/transfer/database.go index e6518e3b235..455038fa9d5 100644 --- a/services/wallet/transfer/database.go +++ b/services/wallet/transfer/database.go @@ -228,49 +228,6 @@ type statementCreator interface { Prepare(query string) (*sql.Stmt, error) } -// Only used by status-mobile -func (db *Database) InsertBlock(chainID uint64, account common.Address, blockNumber *big.Int, blockHash common.Hash) error { - var ( - tx *sql.Tx - ) - tx, err := db.client.Begin() - if err != nil { - return err - } - defer func() { - if err == nil { - err = tx.Commit() - return - } - _ = tx.Rollback() - }() - - blockDB := blockDBFields{ - chainID: chainID, - account: account, - blockNumber: blockNumber, - blockHash: blockHash, - } - return insertBlockDBFields(tx, blockDB) -} - -type blockDBFields struct { - chainID uint64 - account common.Address - blockNumber *big.Int - blockHash common.Hash -} - -func insertBlockDBFields(creator statementCreator, block blockDBFields) error { - insert, err := creator.Prepare("INSERT OR IGNORE INTO blocks(network_id, address, blk_number, blk_hash, loaded) VALUES (?, ?, ?, ?, ?)") - if err != nil { - return err - } - - _, err = insert.Exec(block.chainID, block.account, (*bigint.SQLBigInt)(block.blockNumber), block.blockHash, true) - return err -} - func insertBlocksWithTransactions(chainID uint64, creator statementCreator, headers []*DBHeader) error { insert, err := creator.Prepare("INSERT OR IGNORE INTO blocks(network_id, address, blk_number, blk_hash, loaded) VALUES (?, ?, ?, ?, ?)") if err != nil { diff --git a/services/wallet/transfer/downloader.go b/services/wallet/transfer/downloader.go index 71fd37dc11c..8bc8756c974 100644 --- a/services/wallet/transfer/downloader.go +++ b/services/wallet/transfer/downloader.go @@ -89,49 +89,6 @@ func (d *ETHDownloader) GetTransfersByNumber(ctx context.Context, number *big.In return rst, err } -// Only used by status-mobile -func getTransferByHash(ctx context.Context, client chain.ClientInterface, signer types.Signer, address common.Address, hash common.Hash) (*Transfer, error) { - transaction, _, err := client.TransactionByHash(ctx, hash) - if err != nil { - return nil, err - } - - receipt, err := client.TransactionReceipt(ctx, hash) - if err != nil { - return nil, err - } - - eventType, transactionLog := w_common.GetFirstEvent(receipt.Logs) - transactionType := w_common.EventTypeToSubtransactionType(eventType) - - from, err := types.Sender(signer, transaction) - - if err != nil { - return nil, err - } - - baseGasFee, err := client.GetBaseFeeFromBlock(ctx, big.NewInt(int64(transactionLog.BlockNumber))) - if err != nil { - return nil, err - } - - transfer := &Transfer{ - Type: transactionType, - ID: hash, - Address: address, - BlockNumber: receipt.BlockNumber, - BlockHash: receipt.BlockHash, - Timestamp: uint64(time.Now().Unix()), - Transaction: transaction, - From: from, - Receipt: receipt, - Log: transactionLog, - BaseGasFees: baseGasFee, - } - - return transfer, nil -} - func (d *ETHDownloader) getTransfersInBlock(ctx context.Context, blk *types.Block, accounts []common.Address) ([]Transfer, error) { startTs := time.Now() diff --git a/services/wallet/transfer/reactor.go b/services/wallet/transfer/reactor.go index f058df0cfef..70102f7255b 100644 --- a/services/wallet/transfer/reactor.go +++ b/services/wallet/transfer/reactor.go @@ -121,13 +121,3 @@ func (r *Reactor) createFetchStrategy(chainClients map[uint64]chain.ClientInterf r.blockChainState, ) } - -func (r *Reactor) getTransfersByAddress(ctx context.Context, chainID uint64, address common.Address, toBlock *big.Int, - limit int64) ([]Transfer, error) { - - if r.strategy != nil { - return r.strategy.getTransfersByAddress(ctx, chainID, address, toBlock, limit) - } - - return nil, errors.New(ReactorNotStarted) -} diff --git a/services/wallet/transfer/testutils.go b/services/wallet/transfer/testutils.go index 06b5916c5f9..b4a308ba503 100644 --- a/services/wallet/transfer/testutils.go +++ b/services/wallet/transfer/testutils.go @@ -326,17 +326,6 @@ func InsertTestTransferWithOptions(tb testing.TB, db *sql.DB, address eth_common blkHash := eth_common.HexToHash("4") - block := blockDBFields{ - chainID: uint64(tr.ChainID), - account: address, - blockNumber: big.NewInt(tr.BlkNumber), - blockHash: blkHash, - } - - // Respect `FOREIGN KEY(network_id,address,blk_hash)` of `transfers` table - err = insertBlockDBFields(tx, block) - require.NoError(tb, err) - receiptStatus := uint64(0) if tr.Success { receiptStatus = 1 diff --git a/services/wallet/transfer/view.go b/services/wallet/transfer/view.go deleted file mode 100644 index f6419b5b7cd..00000000000 --- a/services/wallet/transfer/view.go +++ /dev/null @@ -1,118 +0,0 @@ -package transfer - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - w_common "github.com/status-im/status-go/services/wallet/common" -) - -// View stores only fields used by a client and ensures that all relevant fields are -// encoded in hex. -type View struct { - ID common.Hash `json:"id"` - Type w_common.Type `json:"type"` - Address common.Address `json:"address"` - BlockNumber *hexutil.Big `json:"blockNumber"` - BlockHash common.Hash `json:"blockhash"` - Timestamp hexutil.Uint64 `json:"timestamp"` - GasPrice *hexutil.Big `json:"gasPrice"` - MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` - MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` - EffectiveTip *hexutil.Big `json:"effectiveTip"` - EffectiveGasPrice *hexutil.Big `json:"effectiveGasPrice"` - GasLimit hexutil.Uint64 `json:"gasLimit"` - GasUsed hexutil.Uint64 `json:"gasUsed"` - Nonce hexutil.Uint64 `json:"nonce"` - TxStatus hexutil.Uint64 `json:"txStatus"` - Input hexutil.Bytes `json:"input"` - TxHash common.Hash `json:"txHash"` - Value *hexutil.Big `json:"value"` // Only used for Type EthTransfer and Erc20Transfer - TokenID *hexutil.Big `json:"tokenId"` // Only used for Type Erc721Transfer - From common.Address `json:"from"` - To common.Address `json:"to"` - Contract common.Address `json:"contract"` - NetworkID uint64 `json:"networkId"` - MultiTransactionID int64 `json:"multiTransactionID"` - BaseGasFees string `json:"base_gas_fee"` -} - -func castToTransferViews(transfers []Transfer) []View { - views := make([]View, 0, len(transfers)) - for _, tx := range transfers { - switch tx.Type { - case w_common.EthTransfer, w_common.Erc20Transfer, w_common.Erc721Transfer: - view := CastToTransferView(tx) - views = append(views, view) - } - } - return views -} - -func CastToTransferView(t Transfer) View { - view := View{} - view.ID = t.ID - view.Type = getFixedTransferType(t) - view.Address = t.Address - view.BlockNumber = (*hexutil.Big)(t.BlockNumber) - view.BlockHash = t.BlockHash - view.Timestamp = hexutil.Uint64(t.Timestamp) - view.GasPrice = (*hexutil.Big)(t.Transaction.GasPrice()) - if t.BaseGasFees != "" { - baseFee := new(big.Int) - baseFee.SetString(t.BaseGasFees[2:], 16) - tip := t.Transaction.EffectiveGasTipValue(baseFee) - - view.EffectiveTip = (*hexutil.Big)(tip) - price := new(big.Int).Add(baseFee, tip) - view.EffectiveGasPrice = (*hexutil.Big)(price) - } - view.MaxFeePerGas = (*hexutil.Big)(t.Transaction.GasFeeCap()) - view.MaxPriorityFeePerGas = (*hexutil.Big)(t.Transaction.GasTipCap()) - view.GasLimit = hexutil.Uint64(t.Transaction.Gas()) - view.GasUsed = hexutil.Uint64(t.Receipt.GasUsed) - view.BaseGasFees = t.BaseGasFees - view.Nonce = hexutil.Uint64(t.Transaction.Nonce()) - view.TxStatus = hexutil.Uint64(t.Receipt.Status) - view.Input = hexutil.Bytes(t.Transaction.Data()) - view.TxHash = t.Transaction.Hash() - view.NetworkID = t.NetworkID - - value := new(hexutil.Big) - tokenID := new(hexutil.Big) - - switch view.Type { - case w_common.EthTransfer: - view.From = t.From - if t.Transaction.To() != nil { - view.To = *t.Transaction.To() - } - value = (*hexutil.Big)(t.Transaction.Value()) - view.Contract = t.Receipt.ContractAddress - case w_common.Erc20Transfer: - view.Contract = t.Log.Address - from, to, valueInt := w_common.ParseErc20TransferLog(t.Log) - view.From, view.To, value = from, to, (*hexutil.Big)(valueInt) - case w_common.Erc721Transfer: - view.Contract = t.Log.Address - from, to, tokenIDInt := w_common.ParseErc721TransferLog(t.Log) - view.From, view.To, tokenID = from, to, (*hexutil.Big)(tokenIDInt) - } - - view.MultiTransactionID = int64(t.MultiTransactionID) - view.Value = value - view.TokenID = tokenID - - return view -} - -func getFixedTransferType(tx Transfer) w_common.Type { - // erc721 transfers share signature with erc20 ones, so they both used to be categorized as erc20 - // by the Downloader. We fix this here since they might be mis-categorized in the db. - if tx.Type == w_common.Erc20Transfer { - eventType := w_common.GetEventType(tx.Log) - return w_common.EventTypeToSubtransactionType(eventType) - } - return tx.Type -}