-
Notifications
You must be signed in to change notification settings - Fork 21.9k
accounts/abi: fix event tupleUnpack errors + cosmetic cleaning #15452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ebb68bd
6d604a8
f1e9e83
f0fc23b
882a32a
2aeb255
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,15 +18,52 @@ package abi | |
|
|
||
| import ( | ||
| "bytes" | ||
| "encoding/hex" | ||
| "encoding/json" | ||
| "math/big" | ||
| "reflect" | ||
| "strings" | ||
| "testing" | ||
|
|
||
| "github.com/ethereum/go-ethereum/common" | ||
| "github.com/ethereum/go-ethereum/crypto" | ||
| "github.com/stretchr/testify/assert" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're pulling in two libraries that produce a big diff (and code) size, and you're the only one using it. I suggest that you create a different PR to start using those two libraries, so that the content of this PR is only about
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, will do that.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Testify is a really convenient library when doing tests. I will extract it from this pull request and do another one then. |
||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| var jsonEventTransfer = []byte(`{ | ||
| "anonymous": false, | ||
| "inputs": [ | ||
| { | ||
| "indexed": true, "name": "from", "type": "address" | ||
| }, { | ||
| "indexed": true, "name": "to", "type": "address" | ||
| }, { | ||
| "indexed": false, "name": "value", "type": "uint256" | ||
| }], | ||
| "name": "Transfer", | ||
| "type": "event" | ||
| }`) | ||
|
|
||
| var jsonEventPledge = []byte(`{ | ||
| "anonymous": false, | ||
| "inputs": [{ | ||
| "indexed": false, "name": "who", "type": "address" | ||
| }, { | ||
| "indexed": false, "name": "wad", "type": "uint128" | ||
| }, { | ||
| "indexed": false, "name": "currency", "type": "bytes3" | ||
| }], | ||
| "name": "Pledge", | ||
| "type": "event" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs a test to take into account static array types.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| }`) | ||
|
|
||
| // 1000000 | ||
| var transferData1 = "00000000000000000000000000000000000000000000000000000000000f4240" | ||
|
|
||
| // "0x00Ce0d46d924CC8437c806721496599FC3FFA268", 2218516807680, "usd" | ||
| var pledgeData1 = "00000000000000000000000000ce0d46d924cc8437c806721496599fc3ffa2680000000000000000000000000000000000000000000000000000020489e800007573640000000000000000000000000000000000000000000000000000000000" | ||
|
|
||
| func TestEventId(t *testing.T) { | ||
| var table = []struct { | ||
| definition string | ||
|
|
@@ -77,3 +114,130 @@ func TestEventMultiValueWithArrayUnpack(t *testing.T) { | |
| require.Equal(t, [2]uint8{1, 2}, rst.Value1) | ||
| require.Equal(t, uint8(3), rst.Value2) | ||
| } | ||
|
|
||
| func TestEventTupleUnpack(t *testing.T) { | ||
|
|
||
| type EventTransfer struct { | ||
| Value *big.Int | ||
| } | ||
|
|
||
| type EventPledge struct { | ||
| Who common.Address | ||
| Wad *big.Int | ||
| Currency [3]byte | ||
| } | ||
|
|
||
| type BadEventPledge struct { | ||
| Who string | ||
| Wad int | ||
| Currency [3]byte | ||
| } | ||
|
|
||
| bigint := new(big.Int) | ||
| bigintExpected := big.NewInt(1000000) | ||
| bigintExpected2 := big.NewInt(2218516807680) | ||
| addr := common.HexToAddress("0x00Ce0d46d924CC8437c806721496599FC3FFA268") | ||
| var testCases = []struct { | ||
| data string | ||
| dest interface{} | ||
| expected interface{} | ||
| jsonLog []byte | ||
| error string | ||
| name string | ||
| }{{ | ||
| transferData1, | ||
| &EventTransfer{}, | ||
| &EventTransfer{Value: bigintExpected}, | ||
| jsonEventTransfer, | ||
| "", | ||
| "Can unpack ERC20 Transfer event into structure", | ||
| }, { | ||
| transferData1, | ||
| &[]interface{}{&bigint}, | ||
| &[]interface{}{&bigintExpected}, | ||
| jsonEventTransfer, | ||
| "", | ||
| "Can unpack ERC20 Transfer event into slice", | ||
| }, { | ||
| pledgeData1, | ||
| &EventPledge{}, | ||
| &EventPledge{ | ||
| addr, | ||
| bigintExpected2, | ||
| [3]byte{'u', 's', 'd'}}, | ||
| jsonEventPledge, | ||
| "", | ||
| "Can unpack Pledge event into structure", | ||
| }, { | ||
| pledgeData1, | ||
| &[]interface{}{&common.Address{}, &bigint, &[3]byte{}}, | ||
| &[]interface{}{ | ||
| &addr, | ||
| &bigintExpected2, | ||
| &[3]byte{'u', 's', 'd'}}, | ||
| jsonEventPledge, | ||
| "", | ||
| "Can unpack Pledge event into slice", | ||
| }, { | ||
| pledgeData1, | ||
| &[3]interface{}{&common.Address{}, &bigint, &[3]byte{}}, | ||
| &[3]interface{}{ | ||
| &addr, | ||
| &bigintExpected2, | ||
| &[3]byte{'u', 's', 'd'}}, | ||
| jsonEventPledge, | ||
| "", | ||
| "Can unpack Pledge event into an array", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I wasn't clear. This is a good test to have but it isn't exactly what I meant when I said add a test for a static array. Relook at what you have written and consider the following problem. Let's assume we create an event of the signature |
||
| }, { | ||
| pledgeData1, | ||
| &[]interface{}{new(int), 0, 0}, | ||
| &[]interface{}{}, | ||
| jsonEventPledge, | ||
| "abi: cannot unmarshal common.Address in to int", | ||
| "Can not unpack Pledge event into slice with wrong types", | ||
| }, { | ||
| pledgeData1, | ||
| &BadEventPledge{}, | ||
| &BadEventPledge{}, | ||
| jsonEventPledge, | ||
| "abi: cannot unmarshal common.Address in to string", | ||
| "Can not unpack Pledge event into struct with wrong filed types", | ||
| }, { | ||
| pledgeData1, | ||
| &[]interface{}{common.Address{}, new(big.Int)}, | ||
| &[]interface{}{}, | ||
| jsonEventPledge, | ||
| "abi: insufficient number of elements in the list/array for unpack, want 3, got 2", | ||
| "Can not unpack Pledge event into too short slice", | ||
| }, { | ||
| pledgeData1, | ||
| new(map[string]interface{}), | ||
| &[]interface{}{}, | ||
| jsonEventPledge, | ||
| "abi: cannot unmarshal tuple into map[string]interface {}", | ||
| "Can not unpack Pledge event into map", | ||
| }} | ||
|
|
||
| for _, tc := range testCases { | ||
| assert := assert.New(t) | ||
| tc := tc | ||
| t.Run(tc.name, func(t *testing.T) { | ||
| err := unpackTestEventData(tc.dest, tc.data, tc.jsonLog, assert) | ||
| if tc.error == "" { | ||
| assert.Nil(err, "Should be able to unpack event data.") | ||
| assert.Equal(tc.expected, tc.dest) | ||
| } else { | ||
| assert.EqualError(err, tc.error) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| func unpackTestEventData(dest interface{}, hexData string, jsonEvent []byte, assert *assert.Assertions) error { | ||
| data, err := hex.DecodeString(hexData) | ||
| assert.NoError(err, "Hex data should be a correct hex-string") | ||
| var e Event | ||
| assert.NoError(json.Unmarshal(jsonEvent, &e), "Should be able to unmarshal event ABI") | ||
| a := ABI{Events: map[string]Event{"e": e}} | ||
| return a.Unpack(dest, "e", data) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that change really necessary? I can see the point (pun intended) of not displaying two dots if that error is subsequently printed as a
%vfollowed by another dot. However, it would be preferable not to add that dot over there, and not clutter the diff with unnecessary entries (more on that later)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was reported by
golinit