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 <itz.s1na@gmail.com>
This commit is contained in:
parent
b92d0ea3bb
commit
00a73fbcce
@ -34,6 +34,11 @@ import (
|
|||||||
|
|
||||||
const basefeeWiggleMultiplier = 2
|
const basefeeWiggleMultiplier = 2
|
||||||
|
|
||||||
|
var (
|
||||||
|
errNoEventSignature = errors.New("no event signature")
|
||||||
|
errEventSignatureMismatch = errors.New("event signature mismatch")
|
||||||
|
)
|
||||||
|
|
||||||
// SignerFn is a signer function callback when a contract requires a method to
|
// SignerFn is a signer function callback when a contract requires a method to
|
||||||
// sign the transaction before submission.
|
// sign the transaction before submission.
|
||||||
type SignerFn func(common.Address, *types.Transaction) (*types.Transaction, error)
|
type SignerFn func(common.Address, *types.Transaction) (*types.Transaction, error)
|
||||||
@ -488,8 +493,12 @@ func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]inter
|
|||||||
|
|
||||||
// UnpackLog unpacks a retrieved log into the provided output structure.
|
// UnpackLog unpacks a retrieved log into the provided output structure.
|
||||||
func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) error {
|
func (c *BoundContract) UnpackLog(out 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 {
|
if log.Topics[0] != c.abi.Events[event].ID {
|
||||||
return fmt.Errorf("event signature mismatch")
|
return errEventSignatureMismatch
|
||||||
}
|
}
|
||||||
if len(log.Data) > 0 {
|
if len(log.Data) > 0 {
|
||||||
if err := c.abi.UnpackIntoInterface(out, event, log.Data); err != nil {
|
if err := c.abi.UnpackIntoInterface(out, event, log.Data); err != nil {
|
||||||
@ -507,8 +516,12 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log)
|
|||||||
|
|
||||||
// UnpackLogIntoMap unpacks a retrieved log into the provided map.
|
// UnpackLogIntoMap unpacks a retrieved log into the provided map.
|
||||||
func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event string, log types.Log) error {
|
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 {
|
if log.Topics[0] != c.abi.Events[event].ID {
|
||||||
return fmt.Errorf("event signature mismatch")
|
return errEventSignatureMismatch
|
||||||
}
|
}
|
||||||
if len(log.Data) > 0 {
|
if len(log.Data) > 0 {
|
||||||
if err := c.abi.UnpackIntoMap(out, event, log.Data); err != nil {
|
if err := c.abi.UnpackIntoMap(out, event, log.Data); err != nil {
|
||||||
|
@ -186,6 +186,23 @@ func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) {
|
|||||||
unpackAndCheck(t, bc, expectedReceivedMap, mockLog)
|
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) {
|
func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) {
|
||||||
sliceBytes, err := rlp.EncodeToBytes([]string{"name1", "name2", "name3", "name4"})
|
sliceBytes, err := rlp.EncodeToBytes([]string{"name1", "name2", "name3", "name4"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user