aboutsummaryrefslogtreecommitdiffstats
path: root/accounts/abi/abi_test.go
diff options
context:
space:
mode:
authorIan Norden <iannordenn@gmail.com>2019-04-01 21:42:59 +0800
committerGuillaume Ballet <gballet@gmail.com>2019-04-01 21:42:59 +0800
commitcd79bc61a983d6482579d12cdd239b37bbfa12ef (patch)
tree9593641a132e53ce6095b1473ff351db6fdf6378 /accounts/abi/abi_test.go
parent86e77900c53ebce3309099a39cbca38eb4d62fdf (diff)
downloadgo-tangerine-cd79bc61a983d6482579d12cdd239b37bbfa12ef.tar
go-tangerine-cd79bc61a983d6482579d12cdd239b37bbfa12ef.tar.gz
go-tangerine-cd79bc61a983d6482579d12cdd239b37bbfa12ef.tar.bz2
go-tangerine-cd79bc61a983d6482579d12cdd239b37bbfa12ef.tar.lz
go-tangerine-cd79bc61a983d6482579d12cdd239b37bbfa12ef.tar.xz
go-tangerine-cd79bc61a983d6482579d12cdd239b37bbfa12ef.tar.zst
go-tangerine-cd79bc61a983d6482579d12cdd239b37bbfa12ef.zip
accounts/abi: generic unpacking of event logs into map[string]interface{} (#18440)
Add methods that allow for the unpacking of event logs into maps (allows for agnostic unpacking of logs)
Diffstat (limited to 'accounts/abi/abi_test.go')
-rw-r--r--accounts/abi/abi_test.go186
1 files changed, 186 insertions, 0 deletions
diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go
index b9444f9f0..42b60a639 100644
--- a/accounts/abi/abi_test.go
+++ b/accounts/abi/abi_test.go
@@ -694,6 +694,192 @@ func TestUnpackEvent(t *testing.T) {
}
}
+func TestUnpackEventIntoMap(t *testing.T) {
+ const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
+ abi, err := JSON(strings.NewReader(abiJSON))
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ const hexdata = `000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
+ data, err := hex.DecodeString(hexdata)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(data)%32 == 0 {
+ t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
+ }
+
+ receivedMap := map[string]interface{}{}
+ expectedReceivedMap := map[string]interface{}{
+ "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
+ "amount": big.NewInt(1),
+ "memo": []byte{88},
+ }
+ if err := abi.UnpackIntoMap(receivedMap, "received", data); err != nil {
+ t.Error(err)
+ }
+ if len(receivedMap) != 3 {
+ t.Error("unpacked `received` map expected to have length 3")
+ }
+ if receivedMap["sender"] != expectedReceivedMap["sender"] {
+ t.Error("unpacked `received` map does not match expected map")
+ }
+ if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
+ t.Error("unpacked `received` map does not match expected map")
+ }
+ if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
+ t.Error("unpacked `received` map does not match expected map")
+ }
+
+ receivedAddrMap := map[string]interface{}{}
+ if err = abi.UnpackIntoMap(receivedAddrMap, "receivedAddr", data); err != nil {
+ t.Error(err)
+ }
+ if len(receivedAddrMap) != 1 {
+ t.Error("unpacked `receivedAddr` map expected to have length 1")
+ }
+ if receivedAddrMap["sender"] != expectedReceivedMap["sender"] {
+ t.Error("unpacked `receivedAddr` map does not match expected map")
+ }
+}
+
+func TestUnpackMethodIntoMap(t *testing.T) {
+ const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]`
+ abi, err := JSON(strings.NewReader(abiJSON))
+ if err != nil {
+ t.Fatal(err)
+ }
+ const hexdata = `00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000015800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000158000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001580000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000015800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000158`
+ data, err := hex.DecodeString(hexdata)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(data)%32 != 0 {
+ t.Errorf("len(data) is %d, want a multiple of 32", len(data))
+ }
+
+ // Tests a method with no outputs
+ receiveMap := map[string]interface{}{}
+ if err = abi.UnpackIntoMap(receiveMap, "receive", data); err != nil {
+ t.Error(err)
+ }
+ if len(receiveMap) > 0 {
+ t.Error("unpacked `receive` map expected to have length 0")
+ }
+
+ // Tests a method with only outputs
+ sendMap := map[string]interface{}{}
+ if err = abi.UnpackIntoMap(sendMap, "send", data); err != nil {
+ t.Error(err)
+ }
+ if len(sendMap) != 1 {
+ t.Error("unpacked `send` map expected to have length 1")
+ }
+ if sendMap["amount"].(*big.Int).Cmp(big.NewInt(1)) != 0 {
+ t.Error("unpacked `send` map expected `amount` value of 1")
+ }
+
+ // Tests a method with outputs and inputs
+ getMap := map[string]interface{}{}
+ if err = abi.UnpackIntoMap(getMap, "get", data); err != nil {
+ t.Error(err)
+ }
+ if len(sendMap) != 1 {
+ t.Error("unpacked `get` map expected to have length 1")
+ }
+ expectedBytes := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0}
+ if !bytes.Equal(getMap["hash"].([]byte), expectedBytes) {
+ t.Errorf("unpacked `get` map expected `hash` value of %v", expectedBytes)
+ }
+}
+
+func TestUnpackIntoMapNamingConflict(t *testing.T) {
+ // Two methods have the same name
+ var abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"get","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]`
+ abi, err := JSON(strings.NewReader(abiJSON))
+ if err != nil {
+ t.Fatal(err)
+ }
+ var hexdata = `00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
+ data, err := hex.DecodeString(hexdata)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(data)%32 == 0 {
+ t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
+ }
+ getMap := map[string]interface{}{}
+ if err = abi.UnpackIntoMap(getMap, "get", data); err == nil {
+ t.Error("naming conflict between two methods; error expected")
+ }
+
+ // Two events have the same name
+ abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"received","type":"event"}]`
+ abi, err = JSON(strings.NewReader(abiJSON))
+ if err != nil {
+ t.Fatal(err)
+ }
+ hexdata = `000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
+ data, err = hex.DecodeString(hexdata)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(data)%32 == 0 {
+ t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
+ }
+ receivedMap := map[string]interface{}{}
+ if err = abi.UnpackIntoMap(receivedMap, "received", data); err != nil {
+ t.Error("naming conflict between two events; no error expected")
+ }
+ if len(receivedMap) != 1 {
+ t.Error("naming conflict between two events; event defined latest in the abi expected to be used")
+ }
+
+ // Method and event have the same name
+ abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"received","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
+ abi, err = JSON(strings.NewReader(abiJSON))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(data)%32 == 0 {
+ t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
+ }
+ if err = abi.UnpackIntoMap(receivedMap, "received", data); err == nil {
+ t.Error("naming conflict between an event and a method; error expected")
+ }
+
+ // Conflict is case sensitive
+ abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"received","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"Received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
+ abi, err = JSON(strings.NewReader(abiJSON))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(data)%32 == 0 {
+ t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
+ }
+ expectedReceivedMap := map[string]interface{}{
+ "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
+ "amount": big.NewInt(1),
+ "memo": []byte{88},
+ }
+ if err = abi.UnpackIntoMap(receivedMap, "Received", data); err != nil {
+ t.Error(err)
+ }
+ if len(receivedMap) != 3 {
+ t.Error("unpacked `received` map expected to have length 3")
+ }
+ if receivedMap["sender"] != expectedReceivedMap["sender"] {
+ t.Error("unpacked `received` map does not match expected map")
+ }
+ if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
+ t.Error("unpacked `received` map does not match expected map")
+ }
+ if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
+ t.Error("unpacked `received` map does not match expected map")
+ }
+}
+
func TestABI_MethodById(t *testing.T) {
const abiJSON = `[
{"type":"function","name":"receive","constant":false,"inputs":[{"name":"memo","type":"bytes"}],"outputs":[],"payable":true,"stateMutability":"payable"},