From 6b9cd1847d214fbf92da4a1776e8be58d486fa29 Mon Sep 17 00:00:00 2001 From: Bui Quang Minh Date: Wed, 22 Nov 2023 14:00:04 +0700 Subject: [PATCH] rpc/client: check the context before sending message We observe failure in TestEthClient/TxInBlockInterrupted which can be reproduced by go test -test.v -run=^TestEthClient/TxInBlockInterrupted --count=100 === RUN TestEthClient/TxInBlockInterrupted ethclient_test.go:399: transaction should be nil --- FAIL: TestEthClient (0.03s) The testcase expects to get context cancel error when cancelling context passed to the ethclient call before doing the call. However, the rpc client's send does not guarantee that order. It uses select to wait on sending action and context.Done() simultaneously, so it is possible that the branch of sending action is taken and we get the response without error. This commit adds a non-blocking wait on context.Done() to catch the cancelled context before doing the actually send. --- rpc/client.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rpc/client.go b/rpc/client.go index 2b0016db8f..c779aff243 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -559,6 +559,13 @@ func (c *Client) newMessage(method string, paramsIn ...interface{}) (*jsonrpcMes // send registers op with the dispatch loop, then sends msg on the connection. // if sending fails, op is deregistered. func (c *Client) send(ctx context.Context, op *requestOp, msg interface{}) error { + // Check the context before actually sending message + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + select { case c.reqInit <- op: err := c.write(ctx, msg, false)