vm: implement BigInteger item serialization

This commit is contained in:
Evgenii Stratonikov 2019-11-05 12:07:08 +03:00
parent 25f77257ce
commit cd690803cf
4 changed files with 28 additions and 4 deletions

View file

@ -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

View file

@ -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}

View file

@ -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

View file

@ -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