fix: resolve first tx of block
This is a workaround when fetching unknown tx without receiver
This commit is contained in:
parent
569a401643
commit
0856efff6f
|
@ -38,7 +38,7 @@ type ClientInterface interface {
|
||||||
FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)
|
FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)
|
||||||
BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)
|
BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)
|
||||||
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, 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)
|
GetBaseFeeFromBlock(blockNumber *big.Int) (string, error)
|
||||||
NetworkID() uint64
|
NetworkID() uint64
|
||||||
ToBigInt() *big.Int
|
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.
|
// 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
|
// This function preserves the additional data. This is the cheapest way to obtain
|
||||||
// the block hash for a given block number.
|
// 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")
|
rpcstats.CountCall("eth_FullTransactionByBlockNumberAndIndex")
|
||||||
|
|
||||||
tx, err := c.makeCallSingleReturn(
|
tx, err := c.makeCallSingleReturn(
|
||||||
func() (any, error) {
|
func() (any, error) {
|
||||||
return callFullTransactionByBlockNumberAndIndex(ctx, c.mainRPC, blockNumber, index)
|
return callBlockHashByTransaction(ctx, c.mainRPC, blockNumber, index)
|
||||||
},
|
},
|
||||||
func() (any, error) {
|
func() (any, error) {
|
||||||
return callFullTransactionByBlockNumberAndIndex(ctx, c.fallbackRPC, blockNumber, index)
|
return callBlockHashByTransaction(ctx, c.fallbackRPC, blockNumber, index)
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
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) {
|
func (c *ClientWithFallback) GetWalletNotifier() func(chainId uint64, message string) {
|
||||||
|
|
|
@ -3,8 +3,6 @@ package chain
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
|
@ -28,22 +26,17 @@ type TxExtraInfo struct {
|
||||||
From *common.Address `json:"from,omitempty"`
|
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
|
var json *FullTransaction
|
||||||
err := rpc.CallContext(ctx, &json, "eth_getTransactionByBlockNumberAndIndex", toBlockNumArg(number), hexutil.Uint64(index))
|
err := rpc.CallContext(ctx, &json, "eth_getTransactionByBlockNumberAndIndex", toBlockNumArg(number), hexutil.Uint64(index))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return common.HexToHash(""), err
|
||||||
}
|
}
|
||||||
if json == nil {
|
if json == nil {
|
||||||
return nil, ethereum.NotFound
|
return common.HexToHash(""), ethereum.NotFound
|
||||||
} else if _, r, _ := json.Tx.RawSignatureValues(); r == nil {
|
|
||||||
return nil, fmt.Errorf("server returned transaction without signature")
|
|
||||||
}
|
}
|
||||||
if json.From != nil && json.BlockHash != nil {
|
return *json.BlockHash, nil
|
||||||
setSenderFromServer(json.Tx, *json.From, *json.BlockHash)
|
|
||||||
}
|
|
||||||
return json, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *FullTransaction) UnmarshalJSON(msg []byte) error {
|
func (tx *FullTransaction) UnmarshalJSON(msg []byte) error {
|
||||||
|
@ -71,38 +64,3 @@ func toBlockNumArg(number *big.Int) string {
|
||||||
}
|
}
|
||||||
return hexutil.EncodeBig(number)
|
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")
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,8 +8,6 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
||||||
"github.com/status-im/status-go/rpc/chain"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reader interface for reading balance at a specified address.
|
// 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)
|
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)
|
NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)
|
||||||
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, 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
|
NetworkID() uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/core/types"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
@ -281,21 +280,12 @@ func (tc *TestClient) HeaderByNumber(ctx context.Context, number *big.Int) (*typ
|
||||||
return header, nil
|
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")
|
tc.incCounter("FullTransactionByBlockNumberAndIndex")
|
||||||
if tc.traceAPICalls {
|
if tc.traceAPICalls {
|
||||||
tc.t.Log("FullTransactionByBlockNumberAndIndex")
|
tc.t.Log("FullTransactionByBlockNumberAndIndex")
|
||||||
}
|
}
|
||||||
blockHash := common.BigToHash(blockNumber)
|
return common.BigToHash(blockNumber), nil
|
||||||
tx := &chain.FullTransaction{
|
|
||||||
Tx: &types.Transaction{},
|
|
||||||
TxExtraInfo: chain.TxExtraInfo{
|
|
||||||
BlockNumber: (*hexutil.Big)(big.NewInt(0)),
|
|
||||||
BlockHash: &blockHash,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return tx, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *TestClient) GetBaseFeeFromBlock(blockNumber *big.Int) (string, error) {
|
func (tc *TestClient) GetBaseFeeFromBlock(blockNumber *big.Int) (string, error) {
|
||||||
|
|
|
@ -183,11 +183,11 @@ func checkRangesWithStartBlock(parent context.Context, client balance.Reader, ca
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Obtain block hash from first transaction
|
// Obtain block hash from first transaction
|
||||||
firstTransaction, err := client.FullTransactionByBlockNumberAndIndex(ctx, to, 0)
|
blockHash, err := client.CallBlockHashByTransaction(ctx, to, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.PushHeader(toDBHeader(header, *firstTransaction.BlockHash, account))
|
c.PushHeader(toDBHeader(header, blockHash, account))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
mid := new(big.Int).Add(from, to)
|
mid := new(big.Int).Add(from, to)
|
||||||
|
|
|
@ -8,12 +8,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/status-im/status-go/rpc/chain"
|
|
||||||
"github.com/status-im/status-go/services/wallet/balance"
|
"github.com/status-im/status-go/services/wallet/balance"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
@ -83,15 +81,8 @@ func (f balancesFixture) NetworkID() uint64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f balancesFixture) FullTransactionByBlockNumberAndIndex(ctx context.Context, blockNumber *big.Int, index uint) (*chain.FullTransaction, error) {
|
func (f balancesFixture) CallBlockHashByTransaction(ctx context.Context, blockNumber *big.Int, index uint) (common.Hash, error) {
|
||||||
blockHash := common.HexToHash("0x0")
|
return common.HexToHash("0x0"), nil
|
||||||
return &chain.FullTransaction{
|
|
||||||
Tx: &types.Transaction{},
|
|
||||||
TxExtraInfo: chain.TxExtraInfo{
|
|
||||||
BlockNumber: (*hexutil.Big)(big.NewInt(0)),
|
|
||||||
BlockHash: &blockHash,
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type batchesFixture [][]Transfer
|
type batchesFixture [][]Transfer
|
||||||
|
|
Loading…
Reference in New Issue