neo-go/pkg/core/native/util.go
Roman Khimov 9a06995460 bigint: don't allocate in ToPreallocatedBytes
Turns out, it's almost always allocating because we're mostly dealing with
small integers while the buffer size is calculated in 8-byte chunks here, so
preallocated buffer is always insufficient.

name                   old time/op    new time/op    delta
ToPreallocatedBytes-8    28.5ns ± 7%    19.7ns ± 5%   -30.72%  (p=0.000 n=10+10)

name                   old alloc/op   new alloc/op   delta
ToPreallocatedBytes-8     16.0B ± 0%      0.0B       -100.00%  (p=0.000 n=10+10)

name                   old allocs/op  new allocs/op  delta
ToPreallocatedBytes-8      1.00 ± 0%      0.00       -100.00%  (p=0.000 n=10+10)

Fix StorageItem reuse at the same time. We don't copy when getting values from
the storage, but we don when we're putting them, so buffer reuse could corrupt
old values.
2022-06-02 15:38:39 +03:00

65 lines
1.6 KiB
Go

package native
import (
"encoding/hex"
"fmt"
"math/big"
"github.com/nspcc-dev/neo-go/pkg/core/dao"
"github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
var intOne = big.NewInt(1)
var intTwo = big.NewInt(2)
func getConvertibleFromDAO(id int32, d *dao.Simple, key []byte, conv stackitem.Convertible) error {
si := d.GetStorageItem(id, key)
if si == nil {
return storage.ErrKeyNotFound
}
return stackitem.DeserializeConvertible(si, conv)
}
func putConvertibleToDAO(id int32, d *dao.Simple, key []byte, conv stackitem.Convertible) error {
item, err := conv.ToStackItem()
if err != nil {
return err
}
data, err := d.GetItemCtx().Serialize(item, false)
if err != nil {
return err
}
d.PutStorageItem(id, key, data)
return nil
}
func setIntWithKey(id int32, dao *dao.Simple, key []byte, value int64) {
dao.PutBigInt(id, key, big.NewInt(value))
}
func getIntWithKey(id int32, dao *dao.Simple, key []byte) int64 {
si := dao.GetStorageItem(id, key)
if si == nil {
panic(fmt.Errorf("item with id = %d and key = %s is not initialized", id, hex.EncodeToString(key)))
}
return bigint.FromBytes(si).Int64()
}
// makeUint160Key creates a key from the account script hash.
func makeUint160Key(prefix byte, h util.Uint160) []byte {
k := make([]byte, util.Uint160Size+1)
k[0] = prefix
copy(k[1:], h.BytesBE())
return k
}
func toString(item stackitem.Item) string {
s, err := stackitem.ToString(item)
if err != nil {
panic(err)
}
return s
}