forked from cerc-io/plugeth
accounts/abi: Fix method overwritten by same name methods. (#17099)
* accounts/abi: Fix method overwritten by same name methods. * accounts/abi: Fix method overwritten by same name methods. * accounts/abi: avoid possible name conflict Co-authored-by: Guillaume Ballet <gballet@gmail.com>
This commit is contained in:
parent
f7cdea2bdc
commit
0b26a826e9
@ -136,15 +136,27 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
|
|||||||
}
|
}
|
||||||
// empty defaults to function according to the abi spec
|
// empty defaults to function according to the abi spec
|
||||||
case "function", "":
|
case "function", "":
|
||||||
abi.Methods[field.Name] = Method{
|
name := field.Name
|
||||||
Name: field.Name,
|
_, ok := abi.Methods[name]
|
||||||
|
for idx := 0; ok; idx++ {
|
||||||
|
name = fmt.Sprintf("%s%d", field.Name, idx)
|
||||||
|
_, ok = abi.Methods[name]
|
||||||
|
}
|
||||||
|
abi.Methods[name] = Method{
|
||||||
|
Name: name,
|
||||||
Const: field.Constant,
|
Const: field.Constant,
|
||||||
Inputs: field.Inputs,
|
Inputs: field.Inputs,
|
||||||
Outputs: field.Outputs,
|
Outputs: field.Outputs,
|
||||||
}
|
}
|
||||||
case "event":
|
case "event":
|
||||||
abi.Events[field.Name] = Event{
|
name := field.Name
|
||||||
Name: field.Name,
|
_, ok := abi.Events[name]
|
||||||
|
for idx := 0; ok; idx++ {
|
||||||
|
name = fmt.Sprintf("%s%d", field.Name, idx)
|
||||||
|
_, ok = abi.Events[name]
|
||||||
|
}
|
||||||
|
abi.Events[name] = Event{
|
||||||
|
Name: name,
|
||||||
Anonymous: field.Anonymous,
|
Anonymous: field.Anonymous,
|
||||||
Inputs: field.Inputs,
|
Inputs: field.Inputs,
|
||||||
}
|
}
|
||||||
|
@ -832,9 +832,6 @@ func TestUnpackIntoMapNamingConflict(t *testing.T) {
|
|||||||
if err = abi.UnpackIntoMap(receivedMap, "received", data); err != nil {
|
if err = abi.UnpackIntoMap(receivedMap, "received", data); err != nil {
|
||||||
t.Error("naming conflict between two events; no error expected")
|
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
|
// 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"}]`
|
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"}]`
|
||||||
@ -999,3 +996,45 @@ func TestABI_EventById(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDuplicateMethodNames(t *testing.T) {
|
||||||
|
abiJSON := `[{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"customFallback","type":"string"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]`
|
||||||
|
contractAbi, err := JSON(strings.NewReader(abiJSON))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, ok := contractAbi.Methods["transfer"]; !ok {
|
||||||
|
t.Fatalf("Could not find original method")
|
||||||
|
}
|
||||||
|
if _, ok := contractAbi.Methods["transfer0"]; !ok {
|
||||||
|
t.Fatalf("Could not find duplicate method")
|
||||||
|
}
|
||||||
|
if _, ok := contractAbi.Methods["transfer1"]; !ok {
|
||||||
|
t.Fatalf("Could not find duplicate method")
|
||||||
|
}
|
||||||
|
if _, ok := contractAbi.Methods["transfer2"]; ok {
|
||||||
|
t.Fatalf("Should not have found extra method")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDoubleDuplicateMethodNames checks that if transfer0 already exists, there won't be a name
|
||||||
|
// conflict and that the second transfer method will be renamed transfer1.
|
||||||
|
func TestDoubleDuplicateMethodNames(t *testing.T) {
|
||||||
|
abiJSON := `[{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"}],"name":"transfer0","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"customFallback","type":"string"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]`
|
||||||
|
contractAbi, err := JSON(strings.NewReader(abiJSON))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, ok := contractAbi.Methods["transfer"]; !ok {
|
||||||
|
t.Fatalf("Could not find original method")
|
||||||
|
}
|
||||||
|
if _, ok := contractAbi.Methods["transfer0"]; !ok {
|
||||||
|
t.Fatalf("Could not find duplicate method")
|
||||||
|
}
|
||||||
|
if _, ok := contractAbi.Methods["transfer1"]; !ok {
|
||||||
|
t.Fatalf("Could not find duplicate method")
|
||||||
|
}
|
||||||
|
if _, ok := contractAbi.Methods["transfer2"]; ok {
|
||||||
|
t.Fatalf("Should not have found extra method")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -345,29 +345,3 @@ func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) {
|
|||||||
t.Error("unpacked map does not match expected map")
|
t.Error("unpacked map does not match expected map")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnpackIntoMapNamingConflict(t *testing.T) {
|
|
||||||
hash := crypto.Keccak256Hash([]byte("testName"))
|
|
||||||
mockLog := types.Log{
|
|
||||||
Address: common.HexToAddress("0x0"),
|
|
||||||
Topics: []common.Hash{
|
|
||||||
common.HexToHash("0x0"),
|
|
||||||
hash,
|
|
||||||
},
|
|
||||||
Data: hexutil.MustDecode(hexData),
|
|
||||||
BlockNumber: uint64(26),
|
|
||||||
TxHash: common.HexToHash("0x0"),
|
|
||||||
TxIndex: 111,
|
|
||||||
BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}),
|
|
||||||
Index: 7,
|
|
||||||
Removed: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"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"}]`
|
|
||||||
parsedAbi, _ := abi.JSON(strings.NewReader(abiString))
|
|
||||||
bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil)
|
|
||||||
receivedMap := make(map[string]interface{})
|
|
||||||
if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err == nil {
|
|
||||||
t.Error("naming conflict between two events; error expected")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user