From 4e3f17d06fceb5311289afcbd62e3ece56afac35 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 11 Sep 2024 18:53:26 +0300 Subject: [PATCH] rpcbinding: handle NULL results for structures, fix #3581 Signed-off-by: Roman Khimov --- .../notifications/rpcbindings_extended.out | 10 ++++ .../notifications/rpcbindings_guessed.out | 10 ++++ .../rpcbindings/structs/rpcbindings.out | 55 +++++++++++++++++++ .../structs/rpcbindings_dynamic_hash.out | 55 +++++++++++++++++++ .../rpcbindings/types/rpcbindings.out | 10 ++++ .../types/rpcbindings_dynamic_hash.out | 10 ++++ pkg/smartcontract/rpcbinding/binding.go | 5 ++ 7 files changed, 155 insertions(+) diff --git a/cli/smartcontract/testdata/rpcbindings/notifications/rpcbindings_extended.out b/cli/smartcontract/testdata/rpcbindings/notifications/rpcbindings_extended.out index 15bb84f9bd..d6d383310d 100755 --- a/cli/smartcontract/testdata/rpcbindings/notifications/rpcbindings_extended.out +++ b/cli/smartcontract/testdata/rpcbindings/notifications/rpcbindings_extended.out @@ -186,10 +186,15 @@ func (c *Contract) UnexportedFieldUnsigned() (*transaction.Transaction, error) { } // itemToCrazyStruct converts stack item into *CrazyStruct. +// NULL item is returned as nil pointer without error. func itemToCrazyStruct(item stackitem.Item, err error) (*CrazyStruct, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(CrazyStruct) err = res.FromStackItem(item) return res, err @@ -226,10 +231,15 @@ func (res *CrazyStruct) FromStackItem(item stackitem.Item) error { } // itemToSimpleStruct converts stack item into *SimpleStruct. +// NULL item is returned as nil pointer without error. func itemToSimpleStruct(item stackitem.Item, err error) (*SimpleStruct, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(SimpleStruct) err = res.FromStackItem(item) return res, err diff --git a/cli/smartcontract/testdata/rpcbindings/notifications/rpcbindings_guessed.out b/cli/smartcontract/testdata/rpcbindings/notifications/rpcbindings_guessed.out index aec39c0f39..d10cec3345 100755 --- a/cli/smartcontract/testdata/rpcbindings/notifications/rpcbindings_guessed.out +++ b/cli/smartcontract/testdata/rpcbindings/notifications/rpcbindings_guessed.out @@ -186,10 +186,15 @@ func (c *Contract) UnexportedFieldUnsigned() (*transaction.Transaction, error) { } // itemToUnnamed converts stack item into *Unnamed. +// NULL item is returned as nil pointer without error. func itemToUnnamed(item stackitem.Item, err error) (*Unnamed, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(Unnamed) err = res.FromStackItem(item) return res, err @@ -226,10 +231,15 @@ func (res *Unnamed) FromStackItem(item stackitem.Item) error { } // itemToUnnamedX converts stack item into *UnnamedX. +// NULL item is returned as nil pointer without error. func itemToUnnamedX(item stackitem.Item, err error) (*UnnamedX, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(UnnamedX) err = res.FromStackItem(item) return res, err diff --git a/cli/smartcontract/testdata/rpcbindings/structs/rpcbindings.out b/cli/smartcontract/testdata/rpcbindings/structs/rpcbindings.out index e97cc90d48..fd0bcc6ad6 100644 --- a/cli/smartcontract/testdata/rpcbindings/structs/rpcbindings.out +++ b/cli/smartcontract/testdata/rpcbindings/structs/rpcbindings.out @@ -161,10 +161,15 @@ func (c *ContractReader) Transaction(t *LedgerTransaction) (*LedgerTransaction, } // itemToLedgerBlock converts stack item into *LedgerBlock. +// NULL item is returned as nil pointer without error. func itemToLedgerBlock(item stackitem.Item, err error) (*LedgerBlock, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(LedgerBlock) err = res.FromStackItem(item) return res, err @@ -289,10 +294,15 @@ func (res *LedgerBlock) FromStackItem(item stackitem.Item) error { } // itemToLedgerTransaction converts stack item into *LedgerTransaction. +// NULL item is returned as nil pointer without error. func itemToLedgerTransaction(item stackitem.Item, err error) (*LedgerTransaction, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(LedgerTransaction) err = res.FromStackItem(item) return res, err @@ -385,10 +395,15 @@ func (res *LedgerTransaction) FromStackItem(item stackitem.Item) error { } // itemToManagementABI converts stack item into *ManagementABI. +// NULL item is returned as nil pointer without error. func itemToManagementABI(item stackitem.Item, err error) (*ManagementABI, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementABI) err = res.FromStackItem(item) return res, err @@ -451,10 +466,15 @@ func (res *ManagementABI) FromStackItem(item stackitem.Item) error { } // itemToManagementContract converts stack item into *ManagementContract. +// NULL item is returned as nil pointer without error. func itemToManagementContract(item stackitem.Item, err error) (*ManagementContract, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementContract) err = res.FromStackItem(item) return res, err @@ -519,10 +539,15 @@ func (res *ManagementContract) FromStackItem(item stackitem.Item) error { } // itemToManagementEvent converts stack item into *ManagementEvent. +// NULL item is returned as nil pointer without error. func itemToManagementEvent(item stackitem.Item, err error) (*ManagementEvent, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementEvent) err = res.FromStackItem(item) return res, err @@ -581,10 +606,15 @@ func (res *ManagementEvent) FromStackItem(item stackitem.Item) error { } // itemToManagementGroup converts stack item into *ManagementGroup. +// NULL item is returned as nil pointer without error. func itemToManagementGroup(item stackitem.Item, err error) (*ManagementGroup, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementGroup) err = res.FromStackItem(item) return res, err @@ -631,10 +661,15 @@ func (res *ManagementGroup) FromStackItem(item stackitem.Item) error { } // itemToManagementManifest converts stack item into *ManagementManifest. +// NULL item is returned as nil pointer without error. func itemToManagementManifest(item stackitem.Item, err error) (*ManagementManifest, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementManifest) err = res.FromStackItem(item) return res, err @@ -823,10 +858,15 @@ func (res *ManagementManifest) FromStackItem(item stackitem.Item) error { } // itemToManagementMethod converts stack item into *ManagementMethod. +// NULL item is returned as nil pointer without error. func itemToManagementMethod(item stackitem.Item, err error) (*ManagementMethod, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementMethod) err = res.FromStackItem(item) return res, err @@ -903,10 +943,15 @@ func (res *ManagementMethod) FromStackItem(item stackitem.Item) error { } // itemToManagementParameter converts stack item into *ManagementParameter. +// NULL item is returned as nil pointer without error. func itemToManagementParameter(item stackitem.Item, err error) (*ManagementParameter, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementParameter) err = res.FromStackItem(item) return res, err @@ -952,10 +997,15 @@ func (res *ManagementParameter) FromStackItem(item stackitem.Item) error { } // itemToManagementPermission converts stack item into *ManagementPermission. +// NULL item is returned as nil pointer without error. func itemToManagementPermission(item stackitem.Item, err error) (*ManagementPermission, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementPermission) err = res.FromStackItem(item) return res, err @@ -1024,10 +1074,15 @@ func (res *ManagementPermission) FromStackItem(item stackitem.Item) error { } // itemToStructsInternal converts stack item into *StructsInternal. +// NULL item is returned as nil pointer without error. func itemToStructsInternal(item stackitem.Item, err error) (*StructsInternal, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(StructsInternal) err = res.FromStackItem(item) return res, err diff --git a/cli/smartcontract/testdata/rpcbindings/structs/rpcbindings_dynamic_hash.out b/cli/smartcontract/testdata/rpcbindings/structs/rpcbindings_dynamic_hash.out index 2bc3a0ab35..56814fff42 100755 --- a/cli/smartcontract/testdata/rpcbindings/structs/rpcbindings_dynamic_hash.out +++ b/cli/smartcontract/testdata/rpcbindings/structs/rpcbindings_dynamic_hash.out @@ -157,10 +157,15 @@ func (c *ContractReader) Transaction(t *LedgerTransaction) (*LedgerTransaction, } // itemToLedgerBlock converts stack item into *LedgerBlock. +// NULL item is returned as nil pointer without error. func itemToLedgerBlock(item stackitem.Item, err error) (*LedgerBlock, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(LedgerBlock) err = res.FromStackItem(item) return res, err @@ -285,10 +290,15 @@ func (res *LedgerBlock) FromStackItem(item stackitem.Item) error { } // itemToLedgerTransaction converts stack item into *LedgerTransaction. +// NULL item is returned as nil pointer without error. func itemToLedgerTransaction(item stackitem.Item, err error) (*LedgerTransaction, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(LedgerTransaction) err = res.FromStackItem(item) return res, err @@ -381,10 +391,15 @@ func (res *LedgerTransaction) FromStackItem(item stackitem.Item) error { } // itemToManagementABI converts stack item into *ManagementABI. +// NULL item is returned as nil pointer without error. func itemToManagementABI(item stackitem.Item, err error) (*ManagementABI, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementABI) err = res.FromStackItem(item) return res, err @@ -447,10 +462,15 @@ func (res *ManagementABI) FromStackItem(item stackitem.Item) error { } // itemToManagementContract converts stack item into *ManagementContract. +// NULL item is returned as nil pointer without error. func itemToManagementContract(item stackitem.Item, err error) (*ManagementContract, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementContract) err = res.FromStackItem(item) return res, err @@ -515,10 +535,15 @@ func (res *ManagementContract) FromStackItem(item stackitem.Item) error { } // itemToManagementEvent converts stack item into *ManagementEvent. +// NULL item is returned as nil pointer without error. func itemToManagementEvent(item stackitem.Item, err error) (*ManagementEvent, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementEvent) err = res.FromStackItem(item) return res, err @@ -577,10 +602,15 @@ func (res *ManagementEvent) FromStackItem(item stackitem.Item) error { } // itemToManagementGroup converts stack item into *ManagementGroup. +// NULL item is returned as nil pointer without error. func itemToManagementGroup(item stackitem.Item, err error) (*ManagementGroup, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementGroup) err = res.FromStackItem(item) return res, err @@ -627,10 +657,15 @@ func (res *ManagementGroup) FromStackItem(item stackitem.Item) error { } // itemToManagementManifest converts stack item into *ManagementManifest. +// NULL item is returned as nil pointer without error. func itemToManagementManifest(item stackitem.Item, err error) (*ManagementManifest, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementManifest) err = res.FromStackItem(item) return res, err @@ -819,10 +854,15 @@ func (res *ManagementManifest) FromStackItem(item stackitem.Item) error { } // itemToManagementMethod converts stack item into *ManagementMethod. +// NULL item is returned as nil pointer without error. func itemToManagementMethod(item stackitem.Item, err error) (*ManagementMethod, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementMethod) err = res.FromStackItem(item) return res, err @@ -899,10 +939,15 @@ func (res *ManagementMethod) FromStackItem(item stackitem.Item) error { } // itemToManagementParameter converts stack item into *ManagementParameter. +// NULL item is returned as nil pointer without error. func itemToManagementParameter(item stackitem.Item, err error) (*ManagementParameter, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementParameter) err = res.FromStackItem(item) return res, err @@ -948,10 +993,15 @@ func (res *ManagementParameter) FromStackItem(item stackitem.Item) error { } // itemToManagementPermission converts stack item into *ManagementPermission. +// NULL item is returned as nil pointer without error. func itemToManagementPermission(item stackitem.Item, err error) (*ManagementPermission, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(ManagementPermission) err = res.FromStackItem(item) return res, err @@ -1020,10 +1070,15 @@ func (res *ManagementPermission) FromStackItem(item stackitem.Item) error { } // itemToStructsInternal converts stack item into *StructsInternal. +// NULL item is returned as nil pointer without error. func itemToStructsInternal(item stackitem.Item, err error) (*StructsInternal, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(StructsInternal) err = res.FromStackItem(item) return res, err diff --git a/cli/smartcontract/testdata/rpcbindings/types/rpcbindings.out b/cli/smartcontract/testdata/rpcbindings/types/rpcbindings.out index 7513db9eae..7ef32de131 100644 --- a/cli/smartcontract/testdata/rpcbindings/types/rpcbindings.out +++ b/cli/smartcontract/testdata/rpcbindings/types/rpcbindings.out @@ -370,10 +370,15 @@ func (c *ContractReader) UnnamedStructsX() (*UnnamedX, error) { } // itemToUnnamed converts stack item into *Unnamed. +// NULL item is returned as nil pointer without error. func itemToUnnamed(item stackitem.Item, err error) (*Unnamed, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(Unnamed) err = res.FromStackItem(item) return res, err @@ -404,10 +409,15 @@ func (res *Unnamed) FromStackItem(item stackitem.Item) error { } // itemToUnnamedX converts stack item into *UnnamedX. +// NULL item is returned as nil pointer without error. func itemToUnnamedX(item stackitem.Item, err error) (*UnnamedX, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(UnnamedX) err = res.FromStackItem(item) return res, err diff --git a/cli/smartcontract/testdata/rpcbindings/types/rpcbindings_dynamic_hash.out b/cli/smartcontract/testdata/rpcbindings/types/rpcbindings_dynamic_hash.out index 420c7b2a78..cdd0662877 100755 --- a/cli/smartcontract/testdata/rpcbindings/types/rpcbindings_dynamic_hash.out +++ b/cli/smartcontract/testdata/rpcbindings/types/rpcbindings_dynamic_hash.out @@ -366,10 +366,15 @@ func (c *ContractReader) UnnamedStructsX() (*UnnamedX, error) { } // itemToUnnamed converts stack item into *Unnamed. +// NULL item is returned as nil pointer without error. func itemToUnnamed(item stackitem.Item, err error) (*Unnamed, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(Unnamed) err = res.FromStackItem(item) return res, err @@ -400,10 +405,15 @@ func (res *Unnamed) FromStackItem(item stackitem.Item) error { } // itemToUnnamedX converts stack item into *UnnamedX. +// NULL item is returned as nil pointer without error. func itemToUnnamedX(item stackitem.Item, err error) (*UnnamedX, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new(UnnamedX) err = res.FromStackItem(item) return res, err diff --git a/pkg/smartcontract/rpcbinding/binding.go b/pkg/smartcontract/rpcbinding/binding.go index 22d78318c1..7736e2ed6b 100644 --- a/pkg/smartcontract/rpcbinding/binding.go +++ b/pkg/smartcontract/rpcbinding/binding.go @@ -239,10 +239,15 @@ func New(actor Actor{{- if not (len .Hash) -}}, hash util.Uint160{{- end -}}) *C {{- range $m := .Methods -}}{{template "METHOD" $m }}{{ end -}} {{- range $index, $typ := .NamedTypes }} // itemTo{{toTypeName $typ.Name}} converts stack item into *{{toTypeName $typ.Name}}. +// NULL item is returned as nil pointer without error. func itemTo{{toTypeName $typ.Name}}(item stackitem.Item, err error) (*{{toTypeName $typ.Name}}, error) { if err != nil { return nil, err } + _, null := item.(stackitem.Null) + if null { + return nil, nil + } var res = new({{toTypeName $typ.Name}}) err = res.FromStackItem(item) return res, err