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"}},
|
||||
{"atoi", []string{`"4"`, "10"}},
|
||||
{"atoi10", []string{`"4"`}},
|
||||
{"memoryCompare", []string{"[]byte{1}", "[]byte{2}"}},
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package native
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
|
@ -104,6 +105,12 @@ func newStd() *Std {
|
|||
md = newMethodAndPrice(s.base58Decode, 1<<10, callflag.NoneFlag)
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -278,6 +285,12 @@ func (s *Std) base58Decode(_ *interop.Context, args []stackitem.Item) stackitem.
|
|||
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.
|
||||
func (s *Std) Metadata() *interop.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,
|
||||
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