Skip to content

Commit

Permalink
abi/base: return error for pending call error (#24649)
Browse files Browse the repository at this point in the history
If a pending contract call errors, return that error right away rather
than ignoring it to allow an error somewhere else. This is helpful for
callers to know if perhaps a call failed because of the context deadline
being expired. This change mirrors the behavior of non-pending contract
calls.
  • Loading branch information
JoeGruffins authored and chiphamskymavis committed Jan 22, 2025
1 parent 78a67ce commit a826d3c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 12 deletions.
5 changes: 4 additions & 1 deletion accounts/abi/bind/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,10 @@ func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method stri
return ErrNoPendingState
}
output, err = pb.PendingCallContract(ctx, msg)
if err == nil && len(output) == 0 {
if err != nil {
return err
}
if len(output) == 0 {
// Make sure we have a contract to operate on, and bail out otherwise.
if code, err = pb.PendingCodeAt(ctx, c.address); err != nil {
return err
Expand Down
38 changes: 27 additions & 11 deletions accounts/abi/bind/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,30 +76,42 @@ func (mt *mockTransactor) SendTransaction(ctx context.Context, tx *types.Transac
}

type mockCaller struct {
codeAtBlockNumber *big.Int
callContractBlockNumber *big.Int
pendingCodeAtCalled bool
pendingCallContractCalled bool
codeAtBlockNumber *big.Int
callContractBlockNumber *big.Int
callContractBytes []byte
callContractErr error
codeAtBytes []byte
codeAtErr error
}

func (mc *mockCaller) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) {
mc.codeAtBlockNumber = blockNumber
return []byte{1, 2, 3}, nil
return mc.codeAtBytes, mc.codeAtErr
}

func (mc *mockCaller) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
mc.callContractBlockNumber = blockNumber
return nil, nil
return mc.callContractBytes, mc.callContractErr
}

func (mc *mockCaller) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) {
type mockPendingCaller struct {
*mockCaller
pendingCodeAtBytes []byte
pendingCodeAtErr error
pendingCodeAtCalled bool
pendingCallContractCalled bool
pendingCallContractBytes []byte
pendingCallContractErr error
}

func (mc *mockPendingCaller) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) {
mc.pendingCodeAtCalled = true
return nil, nil
return mc.pendingCodeAtBytes, mc.pendingCodeAtErr
}

func (mc *mockCaller) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) {
func (mc *mockPendingCaller) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) {
mc.pendingCallContractCalled = true
return nil, nil
return mc.pendingCallContractBytes, mc.pendingCallContractErr
}

type mockBlockHashCaller struct {
Expand All @@ -124,7 +136,11 @@ func (mc *mockBlockHashCaller) CallContractAtHash(ctx context.Context, call ethe

func TestPassingBlockNumber(t *testing.T) {

mc := &mockCaller{}
mc := &mockPendingCaller{
mockCaller: &mockCaller{
codeAtBytes: []byte{1, 2, 3},
},
}

bc := bind.NewBoundContract(common.HexToAddress("0x0"), abi.ABI{
Methods: map[string]abi.Method{
Expand Down

0 comments on commit a826d3c

Please sign in to comment.