From 6615cce81d317e88053724952c9f3a4f7da20730 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Thu, 27 Jul 2023 16:28:19 +0300 Subject: [PATCH] rpcclient: adjust `unwrapContract` helper There may be no such contract, then Null stackitem is expected on stack. Signed-off-by: Anna Shaleva --- pkg/rpcclient/management/management.go | 9 ++++++++- pkg/rpcclient/management/management_test.go | 13 ++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/pkg/rpcclient/management/management.go b/pkg/rpcclient/management/management.go index 6c8e375f9..8f13776c2 100644 --- a/pkg/rpcclient/management/management.go +++ b/pkg/rpcclient/management/management.go @@ -105,16 +105,23 @@ func (c *ContractReader) GetContract(hash util.Uint160) (*state.Contract, error) return unwrapContract(c.invoker.Call(Hash, "getContract", hash)) } -// GetContractByID allows to get contract data from its ID. +// GetContractByID allows to get contract data from its ID. In case of missing +// contract it returns nil state.Contract and nil error. func (c *ContractReader) GetContractByID(id int32) (*state.Contract, error) { return unwrapContract(c.invoker.Call(Hash, "getContractById", id)) } +// unwrapContract tries to retrieve state.Contract from the provided result.Invoke. +// If the resulting stack contains stackitem.Null, then nil state and nil error +// will be returned. func unwrapContract(r *result.Invoke, err error) (*state.Contract, error) { itm, err := unwrap.Item(r, err) if err != nil { return nil, err } + if itm.Equals(stackitem.Null{}) { + return nil, nil + } res := new(state.Contract) err = res.FromStackItem(itm) if err != nil { diff --git a/pkg/rpcclient/management/management_test.go b/pkg/rpcclient/management/management_test.go index 31a54484d..5ed8b89bc 100644 --- a/pkg/rpcclient/management/management_test.go +++ b/pkg/rpcclient/management/management_test.go @@ -100,6 +100,17 @@ func TestReader(t *testing.T) { require.NoError(t, err) require.False(t, hm) + ta.res = &result.Invoke{ + State: "HALT", + Stack: []stackitem.Item{ + stackitem.Null{}, + }, + } + + cs, err := man.GetContract(util.Uint160{1, 2, 3}) + require.NoError(t, err) + require.Nil(t, cs) + ta.res = &result.Invoke{ State: "HALT", Stack: []stackitem.Item{ @@ -127,7 +138,7 @@ func TestReader(t *testing.T) { }), }, } - cs, err := man.GetContract(util.Uint160{1, 2, 3}) + cs, err = man.GetContract(util.Uint160{1, 2, 3}) require.NoError(t, err) require.Equal(t, int32(1), cs.ID) require.Equal(t, uint16(0), cs.UpdateCounter)