From f8e3b92816623ea46365093d69452201a77ab810 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH] accounts/abi/bind: handle UnpackLog with zero topics (#26920) Adds error handling for the case that UnpackLog or UnpackLogIntoMap is called with a log that has zero topics. --------- Co-authored-by: Sina Mahmoodi --- accounts/abi/bind/base.go | 15 ++++++++++----- accounts/abi/bind/base_test.go | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 36472f81fe18..abd2e7ad45ba 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -32,12 +32,13 @@ import ( "github.com/XinFinOrg/XDPoSChain/event" ) +const basefeeWiggleMultiplier = 2 + var ( - errNoEventSignature = errors.New("no event signature") + errNoEventSignature = errors.New("no event signature") + errEventSignatureMismatch = errors.New("event signature mismatch") ) -const basefeeWiggleMultiplier = 2 - // SignerFn is a signer function callback when a contract requires a method to // sign the transaction before submission. type SignerFn func(common.Address, *types.Transaction) (*types.Transaction, error) @@ -494,7 +495,7 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) return errNoEventSignature } if log.Topics[0] != c.abi.Events[event].ID { - return errors.New("event signature mismatch") + return errEventSignatureMismatch } if len(log.Data) > 0 { if err := c.abi.UnpackIntoInterface(out, event, log.Data); err != nil { @@ -512,8 +513,12 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) // UnpackLogIntoMap unpacks a retrieved log into the provided map. func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event string, log types.Log) error { + // Anonymous events are not supported. + if len(log.Topics) == 0 { + return errNoEventSignature + } if log.Topics[0] != c.abi.Events[event].ID { - return fmt.Errorf("event signature mismatch") + return errEventSignatureMismatch } if len(log.Data) > 0 { if err := c.abi.UnpackIntoMap(out, event, log.Data); err != nil { diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 97972b352e85..d46ab88b8306 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -219,6 +219,23 @@ func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) { unpackAndCheck(t, bc, expectedReceivedMap, mockLog) } +func TestUnpackAnonymousLogIntoMap(t *testing.T) { + mockLog := newMockLog(nil, common.HexToHash("0x0")) + + abiString := `[{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + var received map[string]interface{} + err := bc.UnpackLogIntoMap(received, "received", mockLog) + if err == nil { + t.Error("unpacking anonymous event is not supported") + } + if err.Error() != "no event signature" { + t.Errorf("expected error 'no event signature', got '%s'", err) + } +} + func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) { sliceBytes, err := rlp.EncodeToBytes([]string{"name1", "name2", "name3", "name4"}) if err != nil {