forked from TrueCloudLab/neoneo-go
native/std: add memoryCompare
method
This commit is contained in:
parent
82a6c3266c
commit
978f4dfbc5
4 changed files with 57 additions and 0 deletions
|
@ -228,6 +228,7 @@ func TestNativeHelpersCompile(t *testing.T) {
|
||||||
{"itoa10", []string{"4"}},
|
{"itoa10", []string{"4"}},
|
||||||
{"atoi", []string{`"4"`, "10"}},
|
{"atoi", []string{`"4"`, "10"}},
|
||||||
{"atoi10", []string{`"4"`}},
|
{"atoi10", []string{`"4"`}},
|
||||||
|
{"memoryCompare", []string{"[]byte{1}", "[]byte{2}"}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package native
|
package native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -104,6 +105,12 @@ func newStd() *Std {
|
||||||
md = newMethodAndPrice(s.base58Decode, 1<<10, callflag.NoneFlag)
|
md = newMethodAndPrice(s.base58Decode, 1<<10, callflag.NoneFlag)
|
||||||
s.AddMethod(md, desc)
|
s.AddMethod(md, desc)
|
||||||
|
|
||||||
|
desc = newDescriptor("memoryCompare", smartcontract.IntegerType,
|
||||||
|
manifest.NewParameter("str1", smartcontract.ByteArrayType),
|
||||||
|
manifest.NewParameter("str2", smartcontract.ByteArrayType))
|
||||||
|
md = newMethodAndPrice(s.memoryCompare, 1<<5, callflag.NoneFlag)
|
||||||
|
s.AddMethod(md, desc)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,6 +285,12 @@ func (s *Std) base58Decode(_ *interop.Context, args []stackitem.Item) stackitem.
|
||||||
return stackitem.NewByteArray(result)
|
return stackitem.NewByteArray(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Std) memoryCompare(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
|
s1 := s.toLimitedBytes(args[0])
|
||||||
|
s2 := s.toLimitedBytes(args[1])
|
||||||
|
return stackitem.NewBigInteger(big.NewInt(int64(bytes.Compare(s1, s2))))
|
||||||
|
}
|
||||||
|
|
||||||
// Metadata implements Contract interface.
|
// Metadata implements Contract interface.
|
||||||
func (s *Std) Metadata() *interop.ContractMD {
|
func (s *Std) Metadata() *interop.ContractMD {
|
||||||
return &s.ContractMD
|
return &s.ContractMD
|
||||||
|
|
|
@ -354,3 +354,38 @@ func TestStdLibSerializeDeserialize(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMemoryCompare(t *testing.T) {
|
||||||
|
s := newStd()
|
||||||
|
ic := &interop.Context{VM: vm.New()}
|
||||||
|
|
||||||
|
check := func(t *testing.T, result int64, s1, s2 string) {
|
||||||
|
actual := s.memoryCompare(ic, []stackitem.Item{stackitem.Make(s1), stackitem.Make(s2)})
|
||||||
|
require.Equal(t, big.NewInt(result), actual.Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
check(t, -1, "a", "ab")
|
||||||
|
check(t, 1, "ab", "a")
|
||||||
|
check(t, 0, "ab", "ab")
|
||||||
|
check(t, -1, "", "a")
|
||||||
|
check(t, 0, "", "")
|
||||||
|
|
||||||
|
t.Run("C# compatibility", func(t *testing.T) {
|
||||||
|
// These tests are taken from C# node.
|
||||||
|
check(t, -1, "abc", "c")
|
||||||
|
check(t, -1, "abc", "d")
|
||||||
|
check(t, 0, "abc", "abc")
|
||||||
|
check(t, -1, "abc", "abcd")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("big arguments", func(t *testing.T) {
|
||||||
|
s1 := stackitem.Make(strings.Repeat("x", stdMaxInputLength+1))
|
||||||
|
s2 := stackitem.Make("xxx")
|
||||||
|
|
||||||
|
require.PanicsWithError(t, ErrTooBigInput.Error(),
|
||||||
|
func() { s.memoryCompare(ic, []stackitem.Item{s1, s2}) })
|
||||||
|
|
||||||
|
require.PanicsWithError(t, ErrTooBigInput.Error(),
|
||||||
|
func() { s.memoryCompare(ic, []stackitem.Item{s2, s1}) })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -113,3 +113,11 @@ func Atoi10(s string) int {
|
||||||
return contract.Call(interop.Hash160(Hash), "atoi", contract.NoneFlag,
|
return contract.Call(interop.Hash160(Hash), "atoi", contract.NoneFlag,
|
||||||
s).(int)
|
s).(int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MemoryCompare is similar to bytes.Compare:
|
||||||
|
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
|
||||||
|
// It uses `memoryCompare` method of StdLib native contract.
|
||||||
|
func MemoryCompare(s1, s2 []byte) int {
|
||||||
|
return contract.Call(interop.Hash160(Hash), "memoryCompare", contract.NoneFlag,
|
||||||
|
s1, s2).(int)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue