Skip to content

Commit 7b20a6b

Browse files
committed
abi/bind: fix error-handling in generated wrappers for functions returning structs (ethereum#22005)
Fixes the template used when generating code, which in some scenarios would lead to panic instead of returning an error.
1 parent ba03b7b commit 7b20a6b

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

accounts/abi/bind/bind_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,45 @@ var bindTests = []struct {
574574
nil,
575575
nil,
576576
},
577+
{
578+
`NonExistentStruct`,
579+
`
580+
contract NonExistentStruct {
581+
function Struct() public view returns(uint256 a, uint256 b) {
582+
return (10, 10);
583+
}
584+
}
585+
`,
586+
[]string{`6080604052348015600f57600080fd5b5060888061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063d5f6622514602d575b600080fd5b6033604c565b6040805192835260208301919091528051918290030190f35b600a809156fea264697066735822beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef64736f6c6343decafe0033`},
587+
[]string{`[{"inputs":[],"name":"Struct","outputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"stateMutability":"pure","type":"function"}]`},
588+
`
589+
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
590+
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
591+
"github.com/XinFinOrg/XDPoSChain/common"
592+
"github.com/XinFinOrg/XDPoSChain/core"
593+
"github.com/XinFinOrg/XDPoSChain/params"
594+
`,
595+
`
596+
// Create a simulator and wrap a non-deployed contract
597+
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{}, 10000000, params.TestXDPoSMockChainConfig)
598+
defer sim.Close()
599+
600+
nonexistent, err := NewNonExistentStruct(common.Address{}, sim)
601+
if err != nil {
602+
t.Fatalf("Failed to access non-existent contract: %v", err)
603+
}
604+
// Ensure that contract calls fail with the appropriate error
605+
if res, err := nonexistent.Struct(nil); err == nil {
606+
t.Fatalf("Call succeeded on non-existent contract: %v", res)
607+
} else if (err != bind.ErrNoCode) {
608+
t.Fatalf("Error mismatch: have %v, want %v", err, bind.ErrNoCode)
609+
}
610+
`,
611+
nil,
612+
nil,
613+
nil,
614+
nil,
615+
},
577616
// Tests that gas estimation works for contracts with weird gas mechanics too.
578617
{
579618
`FunkyGasPattern`,

accounts/abi/bind/template.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,9 @@ var (
303303
err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
304304
{{if .Structured}}
305305
outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} })
306+
if err != nil {
307+
return *outstruct, err
308+
}
306309
{{range $i, $t := .Normalized.Outputs}}
307310
outstruct.{{.Name}} = out[{{$i}}].({{bindtype .Type $structs}}){{end}}
308311

0 commit comments

Comments
 (0)