Skip to content

Commit fc341f4

Browse files
committed
ethclient: use pending block hash to key tx sender cache
1 parent 8a84834 commit fc341f4

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

ethclient/ethclient.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface
158158
if err := json.Unmarshal(raw, &body); err != nil {
159159
return nil, err
160160
}
161+
// Pending blocks do not return a block hash, set it to empty hash explicitly
162+
// for sender caching.
163+
if body.Hash == nil {
164+
tmp := head.Hash()
165+
body.Hash = &tmp
166+
}
167+
161168
// Quick-verify transaction and uncle lists. This mostly helps with debugging the server.
162169
if head.UncleHash == types.EmptyUncleHash && len(body.UncleHashes) > 0 {
163170
return nil, errors.New("server returned non-empty uncle list but block header indicates no uncles")
@@ -198,7 +205,7 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface
198205
// Fill the sender cache of transactions in the block.
199206
txs := make([]*types.Transaction, len(body.Transactions))
200207
for i, tx := range body.Transactions {
201-
if tx.From != nil && body.Hash != nil {
208+
if tx.From != nil {
202209
setSenderFromServer(tx.tx, *tx.From, *body.Hash)
203210
}
204211
txs[i] = tx.tx

ethclient/ethclient_test.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,21 @@ func testAtFunctions(t *testing.T, client *rpc.Client) {
625625
if gas != 21000 {
626626
t.Fatalf("unexpected gas limit: %v", gas)
627627
}
628+
629+
// Verify that sender address of pending transaction is saved in cache.
630+
pendingBlock, err := ec.BlockByNumber(context.Background(), big.NewInt(int64(rpc.PendingBlockNumber)))
631+
if err != nil {
632+
t.Fatalf("unexpected error: %v", err)
633+
}
634+
// No additional RPC should be required, ensure the server is not asked by
635+
// canceling the context.
636+
sender, err := ec.TransactionSender(newCanceledContext(), pendingBlock.Transactions()[0], pendingBlock.Hash(), 0)
637+
if err != nil {
638+
t.Fatal("unable to recover sender:", err)
639+
}
640+
if sender != testAddr {
641+
t.Fatal("wrong sender:", sender)
642+
}
628643
}
629644

630645
func testTransactionSender(t *testing.T, client *rpc.Client) {
@@ -646,10 +661,7 @@ func testTransactionSender(t *testing.T, client *rpc.Client) {
646661

647662
// The sender address is cached in tx1, so no additional RPC should be required in
648663
// TransactionSender. Ensure the server is not asked by canceling the context here.
649-
canceledCtx, cancel := context.WithCancel(context.Background())
650-
cancel()
651-
<-canceledCtx.Done() // Ensure the close of the Done channel
652-
sender1, err := ec.TransactionSender(canceledCtx, tx1, block2.Hash(), 0)
664+
sender1, err := ec.TransactionSender(newCanceledContext(), tx1, block2.Hash(), 0)
653665
if err != nil {
654666
t.Fatal(err)
655667
}
@@ -668,6 +680,13 @@ func testTransactionSender(t *testing.T, client *rpc.Client) {
668680
}
669681
}
670682

683+
func newCanceledContext() context.Context {
684+
ctx, cancel := context.WithCancel(context.Background())
685+
cancel()
686+
<-ctx.Done() // Ensure the close of the Done channel
687+
return ctx
688+
}
689+
671690
func sendTransaction(ec *ethclient.Client) error {
672691
chainID, err := ec.ChainID(context.Background())
673692
if err != nil {

0 commit comments

Comments
 (0)