core: fix native NEO ABI

This commit fixes T5 statediff at block #0. The reason in Management's
storage state. The diff occurs because of inconsistent NEO methods
order. See
https://github.com/neo-project/neo/issues/2766#issue-1257870089.

The current solution is to preserve C#'s order of methods to be
compatible with current testnet.

See also
https://docs.microsoft.com/ru-ru/dotnet/api/system.stringcomparer?view=net-6.0
and
https://stackoverflow.com/questions/28638714/easiest-method-to-orderby-a-string-using-stringcomparison-ordinal
for more details.
This commit is contained in:
Anna Shaleva 2022-06-02 08:00:03 +03:00
parent edb6ca8926
commit ca127f1615
2 changed files with 17 additions and 2 deletions

View file

@ -207,7 +207,7 @@ func (c *ContractMD) AddMethod(md *MethodAndPrice, desc *manifest.Method) {
index := sort.Search(len(c.Manifest.ABI.Methods), func(i int) bool {
md := c.Manifest.ABI.Methods[i]
if md.Name != desc.Name {
return md.Name >= desc.Name
return strings.ToLower(md.Name) >= strings.ToLower(desc.Name)
}
return len(md.Parameters) > len(desc.Parameters)
})
@ -236,7 +236,7 @@ func (c *ContractMD) GetMethodByOffset(offset int) (MethodAndPrice, bool) {
func (c *ContractMD) GetMethod(name string, paramCount int) (MethodAndPrice, bool) {
index := sort.Search(len(c.Methods), func(i int) bool {
md := c.Methods[i]
res := strings.Compare(name, md.MD.Name)
res := strings.Compare(strings.ToLower(name), strings.ToLower(md.MD.Name))
switch res {
case -1, 1:
return res == -1

View file

@ -967,3 +967,18 @@ func TestRuntimeCheckWitness(t *testing.T) {
})
})
}
// TestNativeGetMethod is needed to ensure that methods list has the same sorting
// rule as we expect inside the `ContractMD.GetMethod`.
func TestNativeGetMethod(t *testing.T) {
cfg := config.ProtocolConfiguration{P2PSigExtensions: true}
cs := native.NewContracts(cfg)
for _, c := range cs.Contracts {
t.Run(c.Metadata().Name, func(t *testing.T) {
for _, m := range c.Metadata().Methods {
_, ok := c.Metadata().GetMethod(m.MD.Name, len(m.MD.Parameters))
require.True(t, ok)
}
})
}
}