From d9b4da31a1c9fc77325c26ba3c18b3658778091e Mon Sep 17 00:00:00 2001 From: Zsolt Felfoldi Date: Thu, 30 May 2024 08:45:27 +0200 Subject: [PATCH] ethclient/lightclient: implement SendTransaction and PendingNonceAt --- ethclient/lightclient/lightclient.go | 44 +++++++++++++++++++++++++++ ethclient/lightclient/transactions.go | 15 +++++++++ 2 files changed, 59 insertions(+) diff --git a/ethclient/lightclient/lightclient.go b/ethclient/lightclient/lightclient.go index f11db0abfe..7c763818ed 100644 --- a/ethclient/lightclient/lightclient.go +++ b/ethclient/lightclient/lightclient.go @@ -241,6 +241,9 @@ func (c *Client) CodeAt(ctx context.Context, account common.Address, blockNumber } func (c *Client) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) { + if blockNumber.IsInt64() && rpc.BlockNumber(blockNumber.Int64()) == rpc.PendingBlockNumber { + return c.PendingNonceAt(ctx, account) + } proof, _, err := c.state.getProof(ctx, blockNumber, account, nil, false) if err != nil { return 0, err @@ -255,3 +258,44 @@ func (c *Client) BlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumbe } return c.txAndReceipts.getBlockReceipts(ctx, hash) } + +// TransactionSender interface { +func (c *Client) SendTransaction(ctx context.Context, tx *types.Transaction) error { + return c.txAndReceipts.sendTransaction(ctx, tx) + //TODO +} + +// PendingStateReader interface { +func (c *Client) PendingBalanceAt(ctx context.Context, account common.Address) (*big.Int, error) { + return c.BalanceAt(ctx, account, big.NewInt(int64(rpc.LatestBlockNumber))) + //TODO subtract upper estimate for pending tx costs? +} + +func (c *Client) PendingStorageAt(ctx context.Context, account common.Address, key common.Hash) ([]byte, error) { + return c.StorageAt(ctx, account, key, big.NewInt(int64(rpc.LatestBlockNumber))) +} + +func (c *Client) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { + return c.CodeAt(ctx, account, big.NewInt(int64(rpc.LatestBlockNumber))) +} + +func (c *Client) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { + nonce, err := c.NonceAt(ctx, account, big.NewInt(int64(rpc.LatestBlockNumber))) + if err != nil { + return 0, err + } + //TODO + return nonce, err +} + +func (c *Client) PendingTransactionCount(ctx context.Context) (uint, error) { + return 0, nil //TODO +} + +// BlockNumberReader interface { +func (c *Client) BlockNumber(ctx context.Context) (uint64, error) { + if head := c.canonicalChain.getHead(); head != nil { + return head.BlockNumber(), nil + } + return 0, errors.New("chain head unknown") +} diff --git a/ethclient/lightclient/transactions.go b/ethclient/lightclient/transactions.go index c542ba032f..d6bc7f6281 100644 --- a/ethclient/lightclient/transactions.go +++ b/ethclient/lightclient/transactions.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core/types" @@ -251,3 +252,17 @@ func (t *txAndReceipts) cacheBlockTxPositions(block *types.Block) { t.txPosCache.Add(tx.Hash(), txInBlock{blockNumber: blockNumber, blockHash: blockHash, index: uint(i)}) } } + +func (t *txAndReceipts) sendTransaction(ctx context.Context, tx *types.Transaction) error { + data, err := tx.MarshalBinary() + if err != nil { + return err + } + if err := t.client.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data)); err != nil { + return err + } + /*t.sentTxLock.Lock() + t.sentTxs[tx.] + t.sentTxLock.Unlock()*/ + return nil +}