From 0856efff6f0ea1e270bdbe462001968c61626bc8 Mon Sep 17 00:00:00 2001 From: Anthony Laibe Date: Wed, 21 Feb 2024 11:50:46 +0100 Subject: [PATCH] fix: resolve first tx of block This is a workaround when fetching unknown tx without receiver --- rpc/chain/client.go | 12 ++--- rpc/chain/rpc.go | 50 ++----------------- services/wallet/balance/balance_cache.go | 4 +- .../transfer/commands_sequential_test.go | 14 +----- services/wallet/transfer/concurrent.go | 4 +- services/wallet/transfer/concurrent_test.go | 13 +---- 6 files changed, 17 insertions(+), 80 deletions(-) diff --git a/rpc/chain/client.go b/rpc/chain/client.go index ee10524cc..726043e89 100644 --- a/rpc/chain/client.go +++ b/rpc/chain/client.go @@ -38,7 +38,7 @@ type ClientInterface interface { FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) - FullTransactionByBlockNumberAndIndex(ctx context.Context, blockNumber *big.Int, index uint) (*FullTransaction, error) + CallBlockHashByTransaction(ctx context.Context, blockNumber *big.Int, index uint) (common.Hash, error) GetBaseFeeFromBlock(blockNumber *big.Int) (string, error) NetworkID() uint64 ToBigInt() *big.Int @@ -877,24 +877,24 @@ func (c *ClientWithFallback) GetBaseFeeFromBlock(blockNumber *big.Int) (string, // go-ethereum's `Transaction` items drop the blkHash obtained during the RPC call. // This function preserves the additional data. This is the cheapest way to obtain // the block hash for a given block number. -func (c *ClientWithFallback) FullTransactionByBlockNumberAndIndex(ctx context.Context, blockNumber *big.Int, index uint) (*FullTransaction, error) { +func (c *ClientWithFallback) CallBlockHashByTransaction(ctx context.Context, blockNumber *big.Int, index uint) (common.Hash, error) { rpcstats.CountCall("eth_FullTransactionByBlockNumberAndIndex") tx, err := c.makeCallSingleReturn( func() (any, error) { - return callFullTransactionByBlockNumberAndIndex(ctx, c.mainRPC, blockNumber, index) + return callBlockHashByTransaction(ctx, c.mainRPC, blockNumber, index) }, func() (any, error) { - return callFullTransactionByBlockNumberAndIndex(ctx, c.fallbackRPC, blockNumber, index) + return callBlockHashByTransaction(ctx, c.fallbackRPC, blockNumber, index) }, true, ) if err != nil { - return nil, err + return common.HexToHash(""), err } - return tx.(*FullTransaction), nil + return tx.(common.Hash), nil } func (c *ClientWithFallback) GetWalletNotifier() func(chainId uint64, message string) { diff --git a/rpc/chain/rpc.go b/rpc/chain/rpc.go index 9bb03b85d..81d422454 100644 --- a/rpc/chain/rpc.go +++ b/rpc/chain/rpc.go @@ -3,8 +3,6 @@ package chain import ( "context" "encoding/json" - "errors" - "fmt" "math/big" "github.com/ethereum/go-ethereum" @@ -28,22 +26,17 @@ type TxExtraInfo struct { From *common.Address `json:"from,omitempty"` } -func callFullTransactionByBlockNumberAndIndex(ctx context.Context, rpc *rpc.Client, number *big.Int, index uint) (*FullTransaction, error) { +func callBlockHashByTransaction(ctx context.Context, rpc *rpc.Client, number *big.Int, index uint) (common.Hash, error) { var json *FullTransaction err := rpc.CallContext(ctx, &json, "eth_getTransactionByBlockNumberAndIndex", toBlockNumArg(number), hexutil.Uint64(index)) if err != nil { - return nil, err + return common.HexToHash(""), err } if json == nil { - return nil, ethereum.NotFound - } else if _, r, _ := json.Tx.RawSignatureValues(); r == nil { - return nil, fmt.Errorf("server returned transaction without signature") + return common.HexToHash(""), ethereum.NotFound } - if json.From != nil && json.BlockHash != nil { - setSenderFromServer(json.Tx, *json.From, *json.BlockHash) - } - return json, nil + return *json.BlockHash, nil } func (tx *FullTransaction) UnmarshalJSON(msg []byte) error { @@ -71,38 +64,3 @@ func toBlockNumArg(number *big.Int) string { } return hexutil.EncodeBig(number) } - -type senderFromServer struct { - addr common.Address - blockhash common.Hash -} - -var errNotCached = errors.New("sender not cached") - -//nolint:errcheck -func setSenderFromServer(tx *types.Transaction, addr common.Address, block common.Hash) { - // Use types.Sender for side-effect to store our signer into the cache. - types.Sender(&senderFromServer{addr, block}, tx) -} - -func (s *senderFromServer) Equal(other types.Signer) bool { - os, ok := other.(*senderFromServer) - return ok && os.blockhash == s.blockhash -} - -func (s *senderFromServer) Sender(tx *types.Transaction) (common.Address, error) { - if s.addr == (common.Address{}) { - return common.Address{}, errNotCached - } - return s.addr, nil -} - -func (s *senderFromServer) ChainID() *big.Int { - panic("can't sign with senderFromServer") -} -func (s *senderFromServer) Hash(tx *types.Transaction) common.Hash { - panic("can't sign with senderFromServer") -} -func (s *senderFromServer) SignatureValues(tx *types.Transaction, sig []byte) (R, S, V *big.Int, err error) { - panic("can't sign with senderFromServer") -} diff --git a/services/wallet/balance/balance_cache.go b/services/wallet/balance/balance_cache.go index 4d9bde8e6..fd0bd7575 100644 --- a/services/wallet/balance/balance_cache.go +++ b/services/wallet/balance/balance_cache.go @@ -8,8 +8,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - - "github.com/status-im/status-go/rpc/chain" ) // Reader interface for reading balance at a specified address. @@ -17,7 +15,7 @@ type Reader interface { BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) - FullTransactionByBlockNumberAndIndex(ctx context.Context, blockNumber *big.Int, index uint) (*chain.FullTransaction, error) + CallBlockHashByTransaction(ctx context.Context, blockNumber *big.Int, index uint) (common.Hash, error) NetworkID() uint64 } diff --git a/services/wallet/transfer/commands_sequential_test.go b/services/wallet/transfer/commands_sequential_test.go index f7245c291..deeb30d0b 100644 --- a/services/wallet/transfer/commands_sequential_test.go +++ b/services/wallet/transfer/commands_sequential_test.go @@ -19,7 +19,6 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/rpc" @@ -281,21 +280,12 @@ func (tc *TestClient) HeaderByNumber(ctx context.Context, number *big.Int) (*typ return header, nil } -func (tc *TestClient) FullTransactionByBlockNumberAndIndex(ctx context.Context, blockNumber *big.Int, index uint) (*chain.FullTransaction, error) { +func (tc *TestClient) CallBlockHashByTransaction(ctx context.Context, blockNumber *big.Int, index uint) (common.Hash, error) { tc.incCounter("FullTransactionByBlockNumberAndIndex") if tc.traceAPICalls { tc.t.Log("FullTransactionByBlockNumberAndIndex") } - blockHash := common.BigToHash(blockNumber) - tx := &chain.FullTransaction{ - Tx: &types.Transaction{}, - TxExtraInfo: chain.TxExtraInfo{ - BlockNumber: (*hexutil.Big)(big.NewInt(0)), - BlockHash: &blockHash, - }, - } - - return tx, nil + return common.BigToHash(blockNumber), nil } func (tc *TestClient) GetBaseFeeFromBlock(blockNumber *big.Int) (string, error) { diff --git a/services/wallet/transfer/concurrent.go b/services/wallet/transfer/concurrent.go index 7183eff0b..78bac025f 100644 --- a/services/wallet/transfer/concurrent.go +++ b/services/wallet/transfer/concurrent.go @@ -183,11 +183,11 @@ func checkRangesWithStartBlock(parent context.Context, client balance.Reader, ca return err } // Obtain block hash from first transaction - firstTransaction, err := client.FullTransactionByBlockNumberAndIndex(ctx, to, 0) + blockHash, err := client.CallBlockHashByTransaction(ctx, to, 0) if err != nil { return err } - c.PushHeader(toDBHeader(header, *firstTransaction.BlockHash, account)) + c.PushHeader(toDBHeader(header, blockHash, account)) return nil } mid := new(big.Int).Add(from, to) diff --git a/services/wallet/transfer/concurrent_test.go b/services/wallet/transfer/concurrent_test.go index 154901d2a..4ecf00c3d 100644 --- a/services/wallet/transfer/concurrent_test.go +++ b/services/wallet/transfer/concurrent_test.go @@ -8,12 +8,10 @@ import ( "testing" "time" - "github.com/status-im/status-go/rpc/chain" "github.com/status-im/status-go/services/wallet/balance" "github.com/stretchr/testify/require" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/common" @@ -83,15 +81,8 @@ func (f balancesFixture) NetworkID() uint64 { return 0 } -func (f balancesFixture) FullTransactionByBlockNumberAndIndex(ctx context.Context, blockNumber *big.Int, index uint) (*chain.FullTransaction, error) { - blockHash := common.HexToHash("0x0") - return &chain.FullTransaction{ - Tx: &types.Transaction{}, - TxExtraInfo: chain.TxExtraInfo{ - BlockNumber: (*hexutil.Big)(big.NewInt(0)), - BlockHash: &blockHash, - }, - }, nil +func (f balancesFixture) CallBlockHashByTransaction(ctx context.Context, blockNumber *big.Int, index uint) (common.Hash, error) { + return common.HexToHash("0x0"), nil } type batchesFixture [][]Transfer