mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-29 23:33:37 +00:00
vm: implement BigInteger item serialization
This commit is contained in:
parent
25f77257ce
commit
cd690803cf
4 changed files with 28 additions and 4 deletions
|
@ -2,8 +2,10 @@ package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/io"
|
"github.com/CityOfZion/neo-go/pkg/io"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type stackItemType byte
|
type stackItemType byte
|
||||||
|
@ -35,7 +37,8 @@ func serializeItemTo(item StackItem, w *io.BinWriter) {
|
||||||
w.WriteLE(byte(booleanT))
|
w.WriteLE(byte(booleanT))
|
||||||
w.WriteLE(t.value)
|
w.WriteLE(t.value)
|
||||||
case *BigIntegerItem:
|
case *BigIntegerItem:
|
||||||
w.Err = errors.New("not implemented")
|
w.WriteLE(byte(integerT))
|
||||||
|
w.WriteBytes(t.Bytes())
|
||||||
case *InteropItem:
|
case *InteropItem:
|
||||||
w.Err = errors.New("not supported")
|
w.Err = errors.New("not supported")
|
||||||
case *ArrayItem:
|
case *ArrayItem:
|
||||||
|
@ -72,8 +75,11 @@ func deserializeItemFrom(r *io.BinReader) StackItem {
|
||||||
r.ReadLE(&b)
|
r.ReadLE(&b)
|
||||||
return NewBoolItem(b)
|
return NewBoolItem(b)
|
||||||
case integerT:
|
case integerT:
|
||||||
r.Err = errors.New("not implemented")
|
data := r.ReadBytes()
|
||||||
return nil
|
num := new(big.Int).SetBytes(util.ArrayReverse(data))
|
||||||
|
return &BigIntegerItem{
|
||||||
|
value: num,
|
||||||
|
}
|
||||||
case arrayT:
|
case arrayT:
|
||||||
r.Err = errors.New("not implemented")
|
r.Err = errors.New("not implemented")
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -122,7 +122,7 @@ func (e *Element) Bytes() []byte {
|
||||||
case *ByteArrayItem:
|
case *ByteArrayItem:
|
||||||
return t.value
|
return t.value
|
||||||
case *BigIntegerItem:
|
case *BigIntegerItem:
|
||||||
return util.ArrayReverse(t.value.Bytes()) // neoVM returns in LE
|
return t.Bytes() // neoVM returns in LE
|
||||||
case *BoolItem:
|
case *BoolItem:
|
||||||
if t.value {
|
if t.value {
|
||||||
return []byte{1}
|
return []byte{1}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A StackItem represents the "real" value that is pushed on the stack.
|
// A StackItem represents the "real" value that is pushed on the stack.
|
||||||
|
@ -131,6 +133,11 @@ func NewBigIntegerItem(value int) *BigIntegerItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bytes converts i to a slice of bytes.
|
||||||
|
func (i *BigIntegerItem) Bytes() []byte {
|
||||||
|
return util.ArrayReverse(i.value.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
// Value implements StackItem interface.
|
// Value implements StackItem interface.
|
||||||
func (i *BigIntegerItem) Value() interface{} {
|
func (i *BigIntegerItem) Value() interface{} {
|
||||||
return i.value
|
return i.value
|
||||||
|
|
|
@ -245,6 +245,17 @@ func TestSerializeByteArray(t *testing.T) {
|
||||||
require.Equal(t, value, vm.estack.Top().Bytes())
|
require.Equal(t, value, vm.estack.Top().Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSerializeInteger(t *testing.T) {
|
||||||
|
vm := load(getSerializeProg())
|
||||||
|
value := int64(123)
|
||||||
|
vm.estack.PushVal(value)
|
||||||
|
|
||||||
|
testSerialize(t, vm)
|
||||||
|
|
||||||
|
require.IsType(t, (*BigIntegerItem)(nil), vm.estack.Top().value)
|
||||||
|
require.Equal(t, value, vm.estack.Top().BigInt().Int64())
|
||||||
|
}
|
||||||
|
|
||||||
func callNTimes(n uint16) []byte {
|
func callNTimes(n uint16) []byte {
|
||||||
return makeProgram(
|
return makeProgram(
|
||||||
PUSHBYTES2, Instruction(n), Instruction(n>>8), // little-endian
|
PUSHBYTES2, Instruction(n), Instruction(n>>8), // little-endian
|
||||||
|
|
Loading…
Reference in a new issue