dao: use raw state.StorageItem instead of pointer

It is now a slice, there is no need for additional indirection.
This commit is contained in:
Evgeniy Stratonikov 2021-03-05 17:06:54 +03:00
parent fd4174ad31
commit 55698d0426
25 changed files with 126 additions and 174 deletions

View file

@ -290,7 +290,7 @@ func (chain *FakeChain) GetStateRoot(height uint32) (*state.MPTRootState, error)
} }
// GetStorageItem implements Blockchainer interface. // GetStorageItem implements Blockchainer interface.
func (chain *FakeChain) GetStorageItem(id int32, key []byte) *state.StorageItem { func (chain *FakeChain) GetStorageItem(id int32, key []byte) state.StorageItem {
panic("TODO") panic("TODO")
} }
@ -300,7 +300,7 @@ func (chain *FakeChain) GetTestVM(t trigger.Type, tx *transaction.Transaction, b
} }
// GetStorageItems implements Blockchainer interface. // GetStorageItems implements Blockchainer interface.
func (chain *FakeChain) GetStorageItems(id int32) (map[string]*state.StorageItem, error) { func (chain *FakeChain) GetStorageItems(id int32) (map[string]state.StorageItem, error) {
panic("TODO") panic("TODO")
} }

View file

@ -1124,12 +1124,12 @@ func (bc *Blockchain) GetAppExecResults(hash util.Uint256, trig trigger.Type) ([
} }
// GetStorageItem returns an item from storage. // GetStorageItem returns an item from storage.
func (bc *Blockchain) GetStorageItem(id int32, key []byte) *state.StorageItem { func (bc *Blockchain) GetStorageItem(id int32, key []byte) state.StorageItem {
return bc.dao.GetStorageItem(id, key) return bc.dao.GetStorageItem(id, key)
} }
// GetStorageItems returns all storage items for a given contract id. // GetStorageItems returns all storage items for a given contract id.
func (bc *Blockchain) GetStorageItems(id int32) (map[string]*state.StorageItem, error) { func (bc *Blockchain) GetStorageItems(id int32) (map[string]state.StorageItem, error) {
return bc.dao.GetStorageItems(id) return bc.dao.GetStorageItems(id)
} }

View file

@ -56,8 +56,8 @@ type Blockchainer interface {
GetStandByValidators() keys.PublicKeys GetStandByValidators() keys.PublicKeys
GetStateProof(root util.Uint256, key []byte) ([][]byte, error) GetStateProof(root util.Uint256, key []byte) ([][]byte, error)
GetStateRoot(height uint32) (*state.MPTRootState, error) GetStateRoot(height uint32) (*state.MPTRootState, error)
GetStorageItem(id int32, key []byte) *state.StorageItem GetStorageItem(id int32, key []byte) state.StorageItem
GetStorageItems(id int32) (map[string]*state.StorageItem, error) GetStorageItems(id int32) (map[string]state.StorageItem, error)
GetTestVM(t trigger.Type, tx *transaction.Transaction, b *block.Block) *vm.VM GetTestVM(t trigger.Type, tx *transaction.Transaction, b *block.Block) *vm.VM
GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error) GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error)
SetOracle(service services.Oracle) SetOracle(service services.Oracle)

View file

@ -32,15 +32,15 @@ func TestCachedCachedDao(t *testing.T) {
id := int32(random.Int(0, 1024)) id := int32(random.Int(0, 1024))
key := []byte("qwerty") key := []byte("qwerty")
si := &state.StorageItem{Value: []byte("poiuyt")} si := state.StorageItem("poiuyt")
require.NoError(t, ccdao.PutStorageItem(id, key, si)) require.NoError(t, ccdao.PutStorageItem(id, key, si))
resi := ccdao.GetStorageItem(id, key) resi := ccdao.GetStorageItem(id, key)
assert.Equal(t, si, resi) assert.Equal(t, si, resi)
resi = cdao.GetStorageItem(id, key) resi = cdao.GetStorageItem(id, key)
assert.Equal(t, (*state.StorageItem)(nil), resi) assert.Equal(t, state.StorageItem(nil), resi)
resi = pdao.GetStorageItem(id, key) resi = pdao.GetStorageItem(id, key)
assert.Equal(t, (*state.StorageItem)(nil), resi) assert.Equal(t, state.StorageItem(nil), resi)
cnt, err := ccdao.Persist() cnt, err := ccdao.Persist()
assert.NoError(t, err) assert.NoError(t, err)
@ -48,7 +48,7 @@ func TestCachedCachedDao(t *testing.T) {
resi = cdao.GetStorageItem(id, key) resi = cdao.GetStorageItem(id, key)
assert.Equal(t, si, resi) assert.Equal(t, si, resi)
resi = pdao.GetStorageItem(id, key) resi = pdao.GetStorageItem(id, key)
assert.Equal(t, (*state.StorageItem)(nil), resi) assert.Equal(t, state.StorageItem(nil), resi)
cnt, err = cdao.Persist() cnt, err = cdao.Persist()
assert.NoError(t, err) assert.NoError(t, err)

View file

@ -48,9 +48,9 @@ type DAO interface {
GetNEP17TransferLog(acc util.Uint160, index uint32) (*state.NEP17TransferLog, error) GetNEP17TransferLog(acc util.Uint160, index uint32) (*state.NEP17TransferLog, error)
GetStateRoot(height uint32) (*state.MPTRootState, error) GetStateRoot(height uint32) (*state.MPTRootState, error)
PutStateRoot(root *state.MPTRootState) error PutStateRoot(root *state.MPTRootState) error
GetStorageItem(id int32, key []byte) *state.StorageItem GetStorageItem(id int32, key []byte) state.StorageItem
GetStorageItems(id int32) (map[string]*state.StorageItem, error) GetStorageItems(id int32) (map[string]state.StorageItem, error)
GetStorageItemsWithPrefix(id int32, prefix []byte) (map[string]*state.StorageItem, error) GetStorageItemsWithPrefix(id int32, prefix []byte) (map[string]state.StorageItem, error)
GetTransaction(hash util.Uint256) (*transaction.Transaction, uint32, error) GetTransaction(hash util.Uint256) (*transaction.Transaction, uint32, error)
GetVersion() (string, error) GetVersion() (string, error)
GetWrapped() DAO GetWrapped() DAO
@ -61,7 +61,7 @@ type DAO interface {
PutCurrentHeader(hashAndIndex []byte) error PutCurrentHeader(hashAndIndex []byte) error
PutNEP17Balances(acc util.Uint160, bs *state.NEP17Balances) error PutNEP17Balances(acc util.Uint160, bs *state.NEP17Balances) error
PutNEP17TransferLog(acc util.Uint160, index uint32, lg *state.NEP17TransferLog) error PutNEP17TransferLog(acc util.Uint160, index uint32, lg *state.NEP17TransferLog) error
PutStorageItem(id int32, key []byte, si *state.StorageItem) error PutStorageItem(id int32, key []byte, si state.StorageItem) error
PutVersion(v string) error PutVersion(v string) error
Seek(id int32, prefix []byte, f func(k, v []byte)) Seek(id int32, prefix []byte, f func(k, v []byte))
StoreAsBlock(block *block.Block, buf *io.BufBinWriter) error StoreAsBlock(block *block.Block, buf *io.BufBinWriter) error
@ -359,14 +359,14 @@ func (dao *Simple) PutStateRoot(r *state.MPTRootState) error {
} }
// GetStorageItem returns StorageItem if it exists in the given store. // GetStorageItem returns StorageItem if it exists in the given store.
func (dao *Simple) GetStorageItem(id int32, key []byte) *state.StorageItem { func (dao *Simple) GetStorageItem(id int32, key []byte) state.StorageItem {
b, err := dao.Store.Get(makeStorageItemKey(id, key)) b, err := dao.Store.Get(makeStorageItemKey(id, key))
if err != nil { if err != nil {
return nil return nil
} }
r := io.NewBinReaderFromBuf(b) r := io.NewBinReaderFromBuf(b)
si := &state.StorageItem{} si := state.StorageItem{}
si.DecodeBinary(r) si.DecodeBinary(r)
if r.Err != nil { if r.Err != nil {
return nil return nil
@ -377,7 +377,7 @@ func (dao *Simple) GetStorageItem(id int32, key []byte) *state.StorageItem {
// PutStorageItem puts given StorageItem for given id with given // PutStorageItem puts given StorageItem for given id with given
// key into the given store. // key into the given store.
func (dao *Simple) PutStorageItem(id int32, key []byte, si *state.StorageItem) error { func (dao *Simple) PutStorageItem(id int32, key []byte, si state.StorageItem) error {
stKey := makeStorageItemKey(id, key) stKey := makeStorageItemKey(id, key)
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
si.EncodeBinary(buf.BinWriter) si.EncodeBinary(buf.BinWriter)
@ -396,14 +396,14 @@ func (dao *Simple) DeleteStorageItem(id int32, key []byte) error {
} }
// GetStorageItems returns all storage items for a given id. // GetStorageItems returns all storage items for a given id.
func (dao *Simple) GetStorageItems(id int32) (map[string]*state.StorageItem, error) { func (dao *Simple) GetStorageItems(id int32) (map[string]state.StorageItem, error) {
return dao.GetStorageItemsWithPrefix(id, nil) return dao.GetStorageItemsWithPrefix(id, nil)
} }
// GetStorageItemsWithPrefix returns all storage items with given id for a // GetStorageItemsWithPrefix returns all storage items with given id for a
// given scripthash. // given scripthash.
func (dao *Simple) GetStorageItemsWithPrefix(id int32, prefix []byte) (map[string]*state.StorageItem, error) { func (dao *Simple) GetStorageItemsWithPrefix(id int32, prefix []byte) (map[string]state.StorageItem, error) {
var siMap = make(map[string]*state.StorageItem) var siMap = make(map[string]state.StorageItem)
var err error var err error
saveToMap := func(k, v []byte) { saveToMap := func(k, v []byte) {
@ -411,7 +411,7 @@ func (dao *Simple) GetStorageItemsWithPrefix(id int32, prefix []byte) (map[strin
return return
} }
r := io.NewBinReaderFromBuf(v) r := io.NewBinReaderFromBuf(v)
si := &state.StorageItem{} si := state.StorageItem{}
si.DecodeBinary(r) si.DecodeBinary(r)
if r.Err != nil { if r.Err != nil {
err = r.Err err = r.Err

View file

@ -64,7 +64,7 @@ func TestPutGetStorageItem(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false)
id := int32(random.Int(0, 1024)) id := int32(random.Int(0, 1024))
key := []byte{0} key := []byte{0}
storageItem := &state.StorageItem{Value: []uint8{}} storageItem := state.StorageItem{}
err := dao.PutStorageItem(id, key, storageItem) err := dao.PutStorageItem(id, key, storageItem)
require.NoError(t, err) require.NoError(t, err)
gotStorageItem := dao.GetStorageItem(id, key) gotStorageItem := dao.GetStorageItem(id, key)
@ -75,7 +75,7 @@ func TestDeleteStorageItem(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false) dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false)
id := int32(random.Int(0, 1024)) id := int32(random.Int(0, 1024))
key := []byte{0} key := []byte{0}
storageItem := &state.StorageItem{Value: []uint8{}} storageItem := state.StorageItem{}
err := dao.PutStorageItem(id, key, storageItem) err := dao.PutStorageItem(id, key, storageItem)
require.NoError(t, err) require.NoError(t, err)
err = dao.DeleteStorageItem(id, key) err = dao.DeleteStorageItem(id, key)

View file

@ -49,7 +49,7 @@ func storageFind(ic *interop.Context) error {
filteredMap := stackitem.NewMap() filteredMap := stackitem.NewMap()
for k, v := range siMap { for k, v := range siMap {
filteredMap.Add(stackitem.NewByteArray(append(prefix, []byte(k)...)), stackitem.NewByteArray(v.Value)) filteredMap.Add(stackitem.NewByteArray(append(prefix, []byte(k)...)), stackitem.NewByteArray(v))
} }
sort.Slice(filteredMap.Value().([]stackitem.MapElement), func(i, j int) bool { sort.Slice(filteredMap.Value().([]stackitem.MapElement), func(i, j int) bool {
return bytes.Compare(filteredMap.Value().([]stackitem.MapElement)[i].Key.Value().([]byte), return bytes.Compare(filteredMap.Value().([]stackitem.MapElement)[i].Key.Value().([]byte),

View file

@ -51,31 +51,15 @@ func TestStorageFind(t *testing.T) {
skeys := [][]byte{{0x01, 0x02}, {0x02, 0x01}, {0x01, 0x01}, skeys := [][]byte{{0x01, 0x02}, {0x02, 0x01}, {0x01, 0x01},
{0x04, 0x00}, {0x05, 0x00}, {0x06}, {0x07}, {0x08}} {0x04, 0x00}, {0x05, 0x00}, {0x06}, {0x07}, {0x08}}
items := []*state.StorageItem{ items := []state.StorageItem{
{ []byte{0x01, 0x02, 0x03, 0x04},
Value: []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x04, 0x03, 0x02, 0x01},
}, []byte{0x03, 0x04, 0x05, 0x06},
{ []byte{byte(stackitem.ByteArrayT), 2, 0xCA, 0xFE},
Value: []byte{0x04, 0x03, 0x02, 0x01}, []byte{0xFF, 0xFF},
}, rawArr,
{ rawArr0,
Value: []byte{0x03, 0x04, 0x05, 0x06}, rawArr1,
},
{
Value: []byte{byte(stackitem.ByteArrayT), 2, 0xCA, 0xFE},
},
{
Value: []byte{0xFF, 0xFF},
},
{
Value: rawArr,
},
{
Value: rawArr0,
},
{
Value: rawArr1,
},
} }
require.NoError(t, chain.contracts.Management.PutContractState(chain.dao, contractState)) require.NoError(t, chain.contracts.Management.PutContractState(chain.dao, contractState))
@ -121,11 +105,11 @@ func TestStorageFind(t *testing.T) {
testFind(t, 0x01, istorage.FindDefault, []stackitem.Item{ testFind(t, 0x01, istorage.FindDefault, []stackitem.Item{
stackitem.NewStruct([]stackitem.Item{ stackitem.NewStruct([]stackitem.Item{
stackitem.NewByteArray(skeys[2]), stackitem.NewByteArray(skeys[2]),
stackitem.NewByteArray(items[2].Value), stackitem.NewByteArray(items[2]),
}), }),
stackitem.NewStruct([]stackitem.Item{ stackitem.NewStruct([]stackitem.Item{
stackitem.NewByteArray(skeys[0]), stackitem.NewByteArray(skeys[0]),
stackitem.NewByteArray(items[0].Value), stackitem.NewByteArray(items[0]),
}), }),
}) })
}) })
@ -144,13 +128,13 @@ func TestStorageFind(t *testing.T) {
}) })
t.Run("values only", func(t *testing.T) { t.Run("values only", func(t *testing.T) {
testFind(t, 0x01, istorage.FindValuesOnly, []stackitem.Item{ testFind(t, 0x01, istorage.FindValuesOnly, []stackitem.Item{
stackitem.NewByteArray(items[2].Value), stackitem.NewByteArray(items[2]),
stackitem.NewByteArray(items[0].Value), stackitem.NewByteArray(items[0]),
}) })
}) })
t.Run("deserialize values", func(t *testing.T) { t.Run("deserialize values", func(t *testing.T) {
testFind(t, 0x04, istorage.FindValuesOnly|istorage.FindDeserialize, []stackitem.Item{ testFind(t, 0x04, istorage.FindValuesOnly|istorage.FindDeserialize, []stackitem.Item{
stackitem.NewByteArray(items[3].Value[2:]), stackitem.NewByteArray(items[3][2:]),
}) })
t.Run("invalid", func(t *testing.T) { t.Run("invalid", func(t *testing.T) {
v.Estack().PushVal(istorage.FindDeserialize) v.Estack().PushVal(istorage.FindDeserialize)

View file

@ -85,8 +85,8 @@ func storageGet(ic *interop.Context) error {
} }
key := ic.VM.Estack().Pop().Bytes() key := ic.VM.Estack().Pop().Bytes()
si := ic.DAO.GetStorageItem(stc.ID, key) si := ic.DAO.GetStorageItem(stc.ID, key)
if si != nil && si.Value != nil { if si != nil {
ic.VM.Estack().PushVal(si.Value) ic.VM.Estack().PushVal([]byte(si))
} else { } else {
ic.VM.Estack().PushVal(stackitem.Null{}) ic.VM.Estack().PushVal(stackitem.Null{})
} }
@ -131,20 +131,19 @@ func putWithContext(ic *interop.Context, stc *StorageContext, key []byte, value
si := ic.DAO.GetStorageItem(stc.ID, key) si := ic.DAO.GetStorageItem(stc.ID, key)
sizeInc := len(value) sizeInc := len(value)
if si == nil { if si == nil {
si = &state.StorageItem{} si = state.StorageItem{}
sizeInc = len(key) + len(value) sizeInc = len(key) + len(value)
} else if len(value) != 0 { } else if len(value) != 0 {
if len(value) <= len(si.Value) { if len(value) <= len(si) {
sizeInc = (len(value)-1)/4 + 1 sizeInc = (len(value)-1)/4 + 1
} else if len(si.Value) != 0 { } else if len(si) != 0 {
sizeInc = (len(si.Value)-1)/4 + 1 + len(value) - len(si.Value) sizeInc = (len(si)-1)/4 + 1 + len(value) - len(si)
} }
} }
if !ic.VM.AddGas(int64(sizeInc) * ic.Chain.GetPolicer().GetStoragePrice()) { if !ic.VM.AddGas(int64(sizeInc) * ic.Chain.GetPolicer().GetStoragePrice()) {
return errGasLimitExceeded return errGasLimitExceeded
} }
si.Value = value return ic.DAO.PutStorageItem(stc.ID, key, value)
return ic.DAO.PutStorageItem(stc.ID, key, si)
} }
// storagePut puts key-value pair into the storage. // storagePut puts key-value pair into the storage.

View file

@ -257,7 +257,7 @@ func (s *Designate) GetDesignatedByRole(d dao.DAO, r Role, index uint32) (keys.P
} }
var ns NodeList var ns NodeList
var bestIndex uint32 var bestIndex uint32
var resSi *state.StorageItem var resSi state.StorageItem
for k, si := range kvs { for k, si := range kvs {
if len(k) < 4 { if len(k) < 4 {
continue continue
@ -269,7 +269,7 @@ func (s *Designate) GetDesignatedByRole(d dao.DAO, r Role, index uint32) (keys.P
} }
} }
if resSi != nil { if resSi != nil {
reader := io.NewBinReaderFromBuf(resSi.Value) reader := io.NewBinReaderFromBuf(resSi)
ns.DecodeBinary(reader) ns.DecodeBinary(reader)
if reader.Err != nil { if reader.Err != nil {
return nil, 0, reader.Err return nil, 0, reader.Err
@ -324,8 +324,7 @@ func (s *Designate) DesignateAsRole(ic *interop.Context, r Role, pubs keys.Publi
} }
sort.Sort(pubs) sort.Sort(pubs)
s.rolesChangedFlag.Store(true) s.rolesChangedFlag.Store(true)
si = &state.StorageItem{Value: NodeList(pubs).Bytes()} return ic.DAO.PutStorageItem(s.ID, key, NodeList(pubs).Bytes())
return ic.DAO.PutStorageItem(s.ID, key, si)
} }
func (s *Designate) getRole(item stackitem.Item) (Role, bool) { func (s *Designate) getRole(item stackitem.Item) (Role, bool) {

View file

@ -489,7 +489,7 @@ func (m *Management) InitializeCache(d dao.DAO) error {
} }
var cs state.Contract var cs state.Contract
r = io.NewBinReaderFromBuf(si.Value) r = io.NewBinReaderFromBuf(si)
cs.DecodeBinary(r) cs.DecodeBinary(r)
if r.Err != nil { if r.Err != nil {
initErr = r.Err initErr = r.Err
@ -546,10 +546,10 @@ func (m *Management) getNextContractID(d dao.DAO) (int32, error) {
return 0, errors.New("nextAvailableID is not initialized") return 0, errors.New("nextAvailableID is not initialized")
} }
id := bigint.FromBytes(si.Value) id := bigint.FromBytes(si)
ret := int32(id.Int64()) ret := int32(id.Int64())
id.Add(id, intOne) id.Add(id, intOne)
si.Value = bigint.ToPreallocatedBytes(id, si.Value) si = bigint.ToPreallocatedBytes(id, si)
return ret, d.PutStorageItem(m.ID, keyNextAvailableID, si) return ret, d.PutStorageItem(m.ID, keyNextAvailableID, si)
} }

View file

@ -79,7 +79,7 @@ func TestManagement_Initialize(t *testing.T) {
t.Run("invalid contract state", func(t *testing.T) { t.Run("invalid contract state", func(t *testing.T) {
d := dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false) d := dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false)
mgmt := newManagement() mgmt := newManagement()
require.NoError(t, d.PutStorageItem(mgmt.ID, []byte{prefixContract}, &state.StorageItem{Value: []byte{0xFF}})) require.NoError(t, d.PutStorageItem(mgmt.ID, []byte{prefixContract}, state.StorageItem{0xFF}))
require.Error(t, mgmt.InitializeCache(d)) require.Error(t, mgmt.InitializeCache(d))
}) })
} }

View file

@ -259,8 +259,7 @@ func (n *NameService) setPrice(ic *interop.Context, args []stackitem.Item) stack
} }
n.checkCommittee(ic) n.checkCommittee(ic)
si := &state.StorageItem{Value: bigint.ToBytes(price)} err := ic.DAO.PutStorageItem(n.ID, []byte{prefixDomainPrice}, bigint.ToBytes(price))
err := ic.DAO.PutStorageItem(n.ID, []byte{prefixDomainPrice}, si)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -273,7 +272,7 @@ func (n *NameService) getPrice(ic *interop.Context, _ []stackitem.Item) stackite
func (n *NameService) getPriceInternal(d dao.DAO) *big.Int { func (n *NameService) getPriceInternal(d dao.DAO) *big.Int {
si := d.GetStorageItem(n.ID, []byte{prefixDomainPrice}) si := d.GetStorageItem(n.ID, []byte{prefixDomainPrice})
return bigint.FromBytes(si.Value) return bigint.FromBytes(si)
} }
func (n *NameService) parseName(item stackitem.Item) (string, []string, []byte) { func (n *NameService) parseName(item stackitem.Item) (string, []string, []byte) {
@ -337,7 +336,7 @@ func (n *NameService) register(ic *interop.Context, args []stackitem.Item) stack
n.mint(ic, token) n.mint(ic, token)
err := ic.DAO.PutStorageItem(n.ID, err := ic.DAO.PutStorageItem(n.ID,
makeExpirationKey(token.Expiration, token.ID()), makeExpirationKey(token.Expiration, token.ID()),
&state.StorageItem{Value: []byte{0}}) state.StorageItem{0})
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -367,8 +366,7 @@ func (n *NameService) renew(ic *interop.Context, args []stackitem.Item) stackite
} }
binary.BigEndian.PutUint32(key[1:], token.Expiration) binary.BigEndian.PutUint32(key[1:], token.Expiration)
si := &state.StorageItem{Value: []byte{0}} err = ic.DAO.PutStorageItem(n.ID, key, state.StorageItem{0})
err = ic.DAO.PutStorageItem(n.ID, key, si)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -441,7 +439,7 @@ func (n *NameService) setRecord(ic *interop.Context, args []stackitem.Item) stac
panic("not witnessed by admin") panic("not witnessed by admin")
} }
key := makeRecordKey(domain, name, rt) key := makeRecordKey(domain, name, rt)
si := &state.StorageItem{Value: []byte(data)} si := state.StorageItem(data)
if err := ic.DAO.PutStorageItem(n.ID, key, si); err != nil { if err := ic.DAO.PutStorageItem(n.ID, key, si); err != nil {
panic(err) panic(err)
} }
@ -478,7 +476,7 @@ func (n *NameService) getRecord(ic *interop.Context, args []stackitem.Item) stac
if si == nil { if si == nil {
return stackitem.Null{} return stackitem.Null{}
} }
return stackitem.NewByteArray(si.Value) return stackitem.NewByteArray(si)
} }
func (n *NameService) deleteRecord(ic *interop.Context, args []stackitem.Item) stackitem.Item { func (n *NameService) deleteRecord(ic *interop.Context, args []stackitem.Item) stackitem.Item {
@ -541,7 +539,7 @@ func (n *NameService) getRecordsInternal(d dao.DAO, name string) map[RecordType]
if r.Err != nil { if r.Err != nil {
panic(r.Err) panic(r.Err)
} }
res[rt] = string(si.Value) res[rt] = string(si)
}) })
return res return res
} }

View file

@ -41,7 +41,7 @@ func newGAS() *GAS {
} }
func (g *GAS) increaseBalance(_ *interop.Context, _ util.Uint160, si *state.StorageItem, amount *big.Int) error { func (g *GAS) increaseBalance(_ *interop.Context, _ util.Uint160, si *state.StorageItem, amount *big.Int) error {
acc, err := state.NEP17BalanceStateFromBytes(si.Value) acc, err := state.NEP17BalanceStateFromBytes(*si)
if err != nil { if err != nil {
return err return err
} }
@ -52,9 +52,9 @@ func (g *GAS) increaseBalance(_ *interop.Context, _ util.Uint160, si *state.Stor
} }
acc.Balance.Add(&acc.Balance, amount) acc.Balance.Add(&acc.Balance, amount)
if acc.Balance.Sign() != 0 { if acc.Balance.Sign() != 0 {
si.Value = acc.Bytes() *si = acc.Bytes()
} else { } else {
si.Value = nil *si = nil
} }
return nil return nil
} }

View file

@ -172,7 +172,7 @@ func (n *NEO) Initialize(ic *interop.Context) error {
return err return err
} }
err = ic.DAO.PutStorageItem(n.ID, prefixCommittee, &state.StorageItem{Value: cvs.Bytes()}) err = ic.DAO.PutStorageItem(n.ID, prefixCommittee, cvs.Bytes())
if err != nil { if err != nil {
return err return err
} }
@ -192,7 +192,7 @@ func (n *NEO) Initialize(ic *interop.Context) error {
gr := &gasRecord{{Index: index, GASPerBlock: *value}} gr := &gasRecord{{Index: index, GASPerBlock: *value}}
n.gasPerBlock.Store(*gr) n.gasPerBlock.Store(*gr)
n.gasPerBlockChanged.Store(false) n.gasPerBlockChanged.Store(false)
err = ic.DAO.PutStorageItem(n.ID, []byte{prefixVotersCount}, &state.StorageItem{Value: []byte{}}) err = ic.DAO.PutStorageItem(n.ID, []byte{prefixVotersCount}, state.StorageItem{})
if err != nil { if err != nil {
return err return err
} }
@ -206,7 +206,7 @@ func (n *NEO) Initialize(ic *interop.Context) error {
func (n *NEO) InitializeCache(bc blockchainer.Blockchainer, d dao.DAO) error { func (n *NEO) InitializeCache(bc blockchainer.Blockchainer, d dao.DAO) error {
var committee = keysWithVotes{} var committee = keysWithVotes{}
si := d.GetStorageItem(n.ID, prefixCommittee) si := d.GetStorageItem(n.ID, prefixCommittee)
if err := committee.DecodeBytes(si.Value); err != nil { if err := committee.DecodeBytes(si); err != nil {
return err return err
} }
if err := n.updateCache(committee, bc); err != nil { if err := n.updateCache(committee, bc); err != nil {
@ -244,8 +244,7 @@ func (n *NEO) updateCommittee(ic *interop.Context) error {
if !votesChanged { if !votesChanged {
// We need to put in storage anyway, as it affects dumps // We need to put in storage anyway, as it affects dumps
committee := n.committee.Load().(keysWithVotes) committee := n.committee.Load().(keysWithVotes)
si := &state.StorageItem{Value: committee.Bytes()} return ic.DAO.PutStorageItem(n.ID, prefixCommittee, committee.Bytes())
return ic.DAO.PutStorageItem(n.ID, prefixCommittee, si)
} }
_, cvs, err := n.computeCommitteeMembers(ic.Chain, ic.DAO) _, cvs, err := n.computeCommitteeMembers(ic.Chain, ic.DAO)
@ -256,8 +255,7 @@ func (n *NEO) updateCommittee(ic *interop.Context) error {
return err return err
} }
n.votesChanged.Store(false) n.votesChanged.Store(false)
si := &state.StorageItem{Value: cvs.Bytes()} return ic.DAO.PutStorageItem(n.ID, prefixCommittee, cvs.Bytes())
return ic.DAO.PutStorageItem(n.ID, prefixCommittee, si)
} }
// ShouldUpdateCommittee returns true if committee is updated at block h. // ShouldUpdateCommittee returns true if committee is updated at block h.
@ -295,7 +293,6 @@ func (n *NEO) PostPersist(ic *interop.Context) error {
voterReward.Div(voterReward, big.NewInt(100)) voterReward.Div(voterReward, big.NewInt(100))
var cs = n.committee.Load().(keysWithVotes) var cs = n.committee.Load().(keysWithVotes)
var si = new(state.StorageItem)
var key = make([]byte, 38) var key = make([]byte, 38)
for i := range cs { for i := range cs {
if cs[i].Votes.Sign() > 0 { if cs[i].Votes.Sign() > 0 {
@ -312,8 +309,7 @@ func (n *NEO) PostPersist(ic *interop.Context) error {
binary.BigEndian.PutUint32(key[34:], ic.Block.Index+1) binary.BigEndian.PutUint32(key[34:], ic.Block.Index+1)
si.Value = bigint.ToBytes(tmp) if err := ic.DAO.PutStorageItem(n.ID, key, bigint.ToBytes(tmp)); err != nil {
if err := ic.DAO.PutStorageItem(n.ID, key, si); err != nil {
return err return err
} }
} }
@ -346,7 +342,7 @@ func (n *NEO) getGASPerVote(d dao.DAO, key []byte, index ...uint32) []big.Int {
if r.Err != nil { if r.Err != nil {
return return
} }
reward[i] = *bigint.FromBytes(si.Value) reward[i] = *bigint.FromBytes(si)
} }
} }
} }
@ -355,7 +351,7 @@ func (n *NEO) getGASPerVote(d dao.DAO, key []byte, index ...uint32) []big.Int {
} }
func (n *NEO) increaseBalance(ic *interop.Context, h util.Uint160, si *state.StorageItem, amount *big.Int) error { func (n *NEO) increaseBalance(ic *interop.Context, h util.Uint160, si *state.StorageItem, amount *big.Int) error {
acc, err := state.NEOBalanceStateFromBytes(si.Value) acc, err := state.NEOBalanceStateFromBytes(*si)
if err != nil { if err != nil {
return err return err
} }
@ -366,7 +362,7 @@ func (n *NEO) increaseBalance(ic *interop.Context, h util.Uint160, si *state.Sto
return err return err
} }
if amount.Sign() == 0 { if amount.Sign() == 0 {
si.Value = acc.Bytes() *si = acc.Bytes()
return nil return nil
} }
if err := n.ModifyAccountVotes(acc, ic.DAO, amount, false); err != nil { if err := n.ModifyAccountVotes(acc, ic.DAO, amount, false); err != nil {
@ -379,9 +375,9 @@ func (n *NEO) increaseBalance(ic *interop.Context, h util.Uint160, si *state.Sto
} }
acc.Balance.Add(&acc.Balance, amount) acc.Balance.Add(&acc.Balance, amount)
if acc.Balance.Sign() != 0 { if acc.Balance.Sign() != 0 {
si.Value = acc.Bytes() *si = acc.Bytes()
} else { } else {
si.Value = nil *si = nil
} }
return nil return nil
} }
@ -426,7 +422,7 @@ func (n *NEO) getSortedGASRecordFromDAO(d dao.DAO) (gasRecord, error) {
for indexBytes, gasValue := range grMap { for indexBytes, gasValue := range grMap {
gr[i] = gasIndexPair{ gr[i] = gasIndexPair{
Index: binary.BigEndian.Uint32([]byte(indexBytes)), Index: binary.BigEndian.Uint32([]byte(indexBytes)),
GASPerBlock: *bigint.FromBytes(gasValue.Value), GASPerBlock: *bigint.FromBytes(gasValue),
} }
i++ i++
} }
@ -533,7 +529,7 @@ func (n *NEO) CalculateBonus(d dao.DAO, acc util.Uint160, end uint32) (*big.Int,
if si == nil { if si == nil {
return nil, storage.ErrKeyNotFound return nil, storage.ErrKeyNotFound
} }
st, err := state.NEOBalanceStateFromBytes(si.Value) st, err := state.NEOBalanceStateFromBytes(si)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -611,15 +607,14 @@ func (n *NEO) registerCandidate(ic *interop.Context, args []stackitem.Item) stac
func (n *NEO) RegisterCandidateInternal(ic *interop.Context, pub *keys.PublicKey) error { func (n *NEO) RegisterCandidateInternal(ic *interop.Context, pub *keys.PublicKey) error {
key := makeValidatorKey(pub) key := makeValidatorKey(pub)
si := ic.DAO.GetStorageItem(n.ID, key) si := ic.DAO.GetStorageItem(n.ID, key)
var c *candidate
if si == nil { if si == nil {
c := &candidate{Registered: true} c = &candidate{Registered: true}
si = &state.StorageItem{Value: c.Bytes()}
} else { } else {
c := new(candidate).FromBytes(si.Value) c = new(candidate).FromBytes(si)
c.Registered = true c.Registered = true
si.Value = c.Bytes()
} }
return ic.DAO.PutStorageItem(n.ID, key, si) return ic.DAO.PutStorageItem(n.ID, key, c.Bytes())
} }
func (n *NEO) unregisterCandidate(ic *interop.Context, args []stackitem.Item) stackitem.Item { func (n *NEO) unregisterCandidate(ic *interop.Context, args []stackitem.Item) stackitem.Item {
@ -642,14 +637,13 @@ func (n *NEO) UnregisterCandidateInternal(ic *interop.Context, pub *keys.PublicK
return nil return nil
} }
n.validators.Store(keys.PublicKeys(nil)) n.validators.Store(keys.PublicKeys(nil))
c := new(candidate).FromBytes(si.Value) c := new(candidate).FromBytes(si)
c.Registered = false c.Registered = false
ok, err := n.dropCandidateIfZero(ic.DAO, pub, c) ok, err := n.dropCandidateIfZero(ic.DAO, pub, c)
if ok { if ok {
return err return err
} }
si.Value = c.Bytes() return ic.DAO.PutStorageItem(n.ID, key, c.Bytes())
return ic.DAO.PutStorageItem(n.ID, key, si)
} }
func (n *NEO) vote(ic *interop.Context, args []stackitem.Item) stackitem.Item { func (n *NEO) vote(ic *interop.Context, args []stackitem.Item) stackitem.Item {
@ -675,7 +669,7 @@ func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pub *keys.Public
if si == nil { if si == nil {
return errors.New("invalid account") return errors.New("invalid account")
} }
acc, err := state.NEOBalanceStateFromBytes(si.Value) acc, err := state.NEOBalanceStateFromBytes(si)
if err != nil { if err != nil {
return err return err
} }
@ -698,8 +692,7 @@ func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pub *keys.Public
if err := n.ModifyAccountVotes(acc, ic.DAO, &acc.Balance, true); err != nil { if err := n.ModifyAccountVotes(acc, ic.DAO, &acc.Balance, true); err != nil {
return err return err
} }
si.Value = acc.Bytes() return ic.DAO.PutStorageItem(n.ID, key, acc.Bytes())
return ic.DAO.PutStorageItem(n.ID, key, si)
} }
// ModifyAccountVotes modifies votes of the specified account by value (can be negative). // ModifyAccountVotes modifies votes of the specified account by value (can be negative).
@ -712,7 +705,7 @@ func (n *NEO) ModifyAccountVotes(acc *state.NEOBalanceState, d dao.DAO, value *b
if si == nil { if si == nil {
return errors.New("invalid validator") return errors.New("invalid validator")
} }
cd := new(candidate).FromBytes(si.Value) cd := new(candidate).FromBytes(si)
cd.Votes.Add(&cd.Votes, value) cd.Votes.Add(&cd.Votes, value)
if !isNewVote { if !isNewVote {
ok, err := n.dropCandidateIfZero(d, acc.VoteTo, cd) ok, err := n.dropCandidateIfZero(d, acc.VoteTo, cd)
@ -723,8 +716,7 @@ func (n *NEO) ModifyAccountVotes(acc *state.NEOBalanceState, d dao.DAO, value *b
return errors.New("validator must be registered") return errors.New("validator must be registered")
} }
n.validators.Store(keys.PublicKeys(nil)) n.validators.Store(keys.PublicKeys(nil))
si.Value = cd.Bytes() return d.PutStorageItem(n.ID, key, cd.Bytes())
return d.PutStorageItem(n.ID, key, si)
} }
return nil return nil
} }
@ -736,7 +728,7 @@ func (n *NEO) getCandidates(d dao.DAO, sortByKey bool) ([]keyWithVotes, error) {
} }
arr := make([]keyWithVotes, 0, len(siMap)) arr := make([]keyWithVotes, 0, len(siMap))
for key, si := range siMap { for key, si := range siMap {
c := new(candidate).FromBytes(si.Value) c := new(candidate).FromBytes(si)
if c.Registered { if c.Registered {
arr = append(arr, keyWithVotes{Key: key, Votes: &c.Votes}) arr = append(arr, keyWithVotes{Key: key, Votes: &c.Votes})
} }
@ -817,9 +809,9 @@ func (n *NEO) modifyVoterTurnout(d dao.DAO, amount *big.Int) error {
if si == nil { if si == nil {
return errors.New("voters count not found") return errors.New("voters count not found")
} }
votersCount := bigint.FromBytes(si.Value) votersCount := bigint.FromBytes(si)
votersCount.Add(votersCount, amount) votersCount.Add(votersCount, amount)
si.Value = bigint.ToBytes(votersCount) si = bigint.ToBytes(votersCount)
return d.PutStorageItem(n.ID, key, si) return d.PutStorageItem(n.ID, key, si)
} }
@ -854,7 +846,7 @@ func (n *NEO) computeCommitteeMembers(bc blockchainer.Blockchainer, d dao.DAO) (
if si == nil { if si == nil {
return nil, nil, errors.New("voters count not found") return nil, nil, errors.New("voters count not found")
} }
votersCount := bigint.FromBytes(si.Value) votersCount := bigint.FromBytes(si)
// votersCount / totalSupply must be >= 0.2 // votersCount / totalSupply must be >= 0.2
votersCount.Mul(votersCount, big.NewInt(effectiveVoterTurnout)) votersCount.Mul(votersCount, big.NewInt(effectiveVoterTurnout))
voterTurnout := votersCount.Div(votersCount, n.getTotalSupply(d)) voterTurnout := votersCount.Div(votersCount, n.getTotalSupply(d))
@ -926,6 +918,5 @@ func (n *NEO) putGASRecord(dao dao.DAO, index uint32, value *big.Int) error {
key := make([]byte, 5) key := make([]byte, 5)
key[0] = prefixGASPerBlock key[0] = prefixGASPerBlock
binary.BigEndian.PutUint32(key[1:], index) binary.BigEndian.PutUint32(key[1:], index)
si := &state.StorageItem{Value: bigint.ToBytes(value)} return dao.PutStorageItem(n.ID, key, bigint.ToBytes(value))
return dao.PutStorageItem(n.ID, key, si)
} }

View file

@ -100,12 +100,11 @@ func (c *nep17TokenNative) getTotalSupply(d dao.DAO) *big.Int {
if si == nil { if si == nil {
return big.NewInt(0) return big.NewInt(0)
} }
return bigint.FromBytes(si.Value) return bigint.FromBytes(si)
} }
func (c *nep17TokenNative) saveTotalSupply(d dao.DAO, supply *big.Int) error { func (c *nep17TokenNative) saveTotalSupply(d dao.DAO, supply *big.Int) error {
si := &state.StorageItem{Value: bigint.ToBytes(supply)} return d.PutStorageItem(c.ID, totalSupplyKey, bigint.ToBytes(supply))
return d.PutStorageItem(c.ID, totalSupplyKey, si)
} }
func (c *nep17TokenNative) Transfer(ic *interop.Context, args []stackitem.Item) stackitem.Item { func (c *nep17TokenNative) Transfer(ic *interop.Context, args []stackitem.Item) stackitem.Item {
@ -168,14 +167,14 @@ func (c *nep17TokenNative) updateAccBalance(ic *interop.Context, acc util.Uint16
if amount.Sign() <= 0 { if amount.Sign() <= 0 {
return errors.New("insufficient funds") return errors.New("insufficient funds")
} }
si = new(state.StorageItem) si = state.StorageItem{}
} }
err := c.incBalance(ic, acc, si, amount) err := c.incBalance(ic, acc, &si, amount)
if err != nil { if err != nil {
return err return err
} }
if si.Value == nil { if si == nil {
err = ic.DAO.DeleteStorageItem(c.ID, key) err = ic.DAO.DeleteStorageItem(c.ID, key)
} else { } else {
err = ic.DAO.PutStorageItem(c.ID, key, si) err = ic.DAO.PutStorageItem(c.ID, key, si)
@ -253,13 +252,13 @@ func (c *nep17TokenNative) addTokens(ic *interop.Context, h util.Uint160, amount
key := makeAccountKey(h) key := makeAccountKey(h)
si := ic.DAO.GetStorageItem(c.ID, key) si := ic.DAO.GetStorageItem(c.ID, key)
if si == nil { if si == nil {
si = new(state.StorageItem) si = state.StorageItem{}
} }
if err := c.incBalance(ic, h, si, amount); err != nil { if err := c.incBalance(ic, h, &si, amount); err != nil {
panic(err) panic(err)
} }
var err error var err error
if si.Value == nil { if si == nil {
err = ic.DAO.DeleteStorageItem(c.ID, key) err = ic.DAO.DeleteStorageItem(c.ID, key)
} else { } else {
err = ic.DAO.PutStorageItem(c.ID, key, si) err = ic.DAO.PutStorageItem(c.ID, key, si)

View file

@ -141,12 +141,11 @@ func (n *nonfungible) TotalSupply(d dao.DAO) *big.Int {
if si == nil { if si == nil {
panic(errors.New("total supply is not initialized")) panic(errors.New("total supply is not initialized"))
} }
return bigint.FromBytes(si.Value) return bigint.FromBytes(si)
} }
func (n *nonfungible) setTotalSupply(d dao.DAO, ts *big.Int) { func (n *nonfungible) setTotalSupply(d dao.DAO, ts *big.Int) {
si := &state.StorageItem{Value: bigint.ToBytes(ts)} err := d.PutStorageItem(n.ID, nftTotalSupplyKey, bigint.ToBytes(ts))
err := d.PutStorageItem(n.ID, nftTotalSupplyKey, si)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -222,7 +221,7 @@ func (n *nonfungible) tokens(ic *interop.Context, args []stackitem.Item) stackit
} }
filteredMap := stackitem.NewMap() filteredMap := stackitem.NewMap()
for k, v := range siMap { for k, v := range siMap {
filteredMap.Add(stackitem.NewByteArray(append(prefix, []byte(k)...)), stackitem.NewByteArray(v.Value)) filteredMap.Add(stackitem.NewByteArray(append(prefix, []byte(k)...)), stackitem.NewByteArray(v))
} }
sort.Slice(filteredMap.Value().([]stackitem.MapElement), func(i, j int) bool { sort.Slice(filteredMap.Value().([]stackitem.MapElement), func(i, j int) bool {
return bytes.Compare(filteredMap.Value().([]stackitem.MapElement)[i].Key.Value().([]byte), return bytes.Compare(filteredMap.Value().([]stackitem.MapElement)[i].Key.Value().([]byte),

View file

@ -166,8 +166,7 @@ func (o *Oracle) PostPersist(ic *interop.Context) error {
if len(*idList) == 0 { if len(*idList) == 0 {
err = ic.DAO.DeleteStorageItem(o.ID, idKey) err = ic.DAO.DeleteStorageItem(o.ID, idKey)
} else { } else {
si := &state.StorageItem{Value: idList.Bytes()} err = ic.DAO.PutStorageItem(o.ID, idKey, idList.Bytes())
err = ic.DAO.PutStorageItem(o.ID, idKey, si)
} }
if err != nil { if err != nil {
return err return err
@ -303,10 +302,10 @@ func (o *Oracle) RequestInternal(ic *interop.Context, url string, filter *string
callingHash := ic.VM.GetCallingScriptHash() callingHash := ic.VM.GetCallingScriptHash()
o.GAS.mint(ic, o.Hash, gas, false) o.GAS.mint(ic, o.Hash, gas, false)
si := ic.DAO.GetStorageItem(o.ID, prefixRequestID) si := ic.DAO.GetStorageItem(o.ID, prefixRequestID)
itemID := bigint.FromBytes(si.Value) itemID := bigint.FromBytes(si)
id := itemID.Uint64() id := itemID.Uint64()
itemID.Add(itemID, intOne) itemID.Add(itemID, intOne)
si.Value = bigint.ToPreallocatedBytes(itemID, si.Value) si = bigint.ToPreallocatedBytes(itemID, si)
if err := ic.DAO.PutStorageItem(o.ID, prefixRequestID, si); err != nil { if err := ic.DAO.PutStorageItem(o.ID, prefixRequestID, si); err != nil {
return err return err
} }
@ -357,9 +356,8 @@ func (o *Oracle) RequestInternal(ic *interop.Context, url string, filter *string
// PutRequestInternal puts oracle request with the specified id to d. // PutRequestInternal puts oracle request with the specified id to d.
func (o *Oracle) PutRequestInternal(id uint64, req *state.OracleRequest, d dao.DAO) error { func (o *Oracle) PutRequestInternal(id uint64, req *state.OracleRequest, d dao.DAO) error {
reqItem := &state.StorageItem{Value: req.Bytes()}
reqKey := makeRequestKey(id) reqKey := makeRequestKey(id)
if err := d.PutStorageItem(o.ID, reqKey, reqItem); err != nil { if err := d.PutStorageItem(o.ID, reqKey, req.Bytes()); err != nil {
return err return err
} }
o.newRequests[id] = req o.newRequests[id] = req
@ -374,8 +372,7 @@ func (o *Oracle) PutRequestInternal(id uint64, req *state.OracleRequest, d dao.D
return fmt.Errorf("there are too many pending requests for %s url", req.URL) return fmt.Errorf("there are too many pending requests for %s url", req.URL)
} }
*lst = append(*lst, id) *lst = append(*lst, id)
si := &state.StorageItem{Value: lst.Bytes()} return d.PutStorageItem(o.ID, key, lst.Bytes())
return d.PutStorageItem(o.ID, key, si)
} }
// GetScriptHash returns script hash or oracle nodes. // GetScriptHash returns script hash or oracle nodes.
@ -429,7 +426,7 @@ func (o *Oracle) getRequests(d dao.DAO) (map[uint64]*state.OracleRequest, error)
if len(k) != 8 { if len(k) != 8 {
return nil, errors.New("invalid request ID") return nil, errors.New("invalid request ID")
} }
r := io.NewBinReaderFromBuf(si.Value) r := io.NewBinReaderFromBuf(si)
req := new(state.OracleRequest) req := new(state.OracleRequest)
req.DecodeBinary(r) req.DecodeBinary(r)
if r.Err != nil { if r.Err != nil {

View file

@ -325,9 +325,7 @@ func (p *Policy) blockAccount(ic *interop.Context, args []stackitem.Item) stacki
key := append([]byte{blockedAccountPrefix}, hash.BytesBE()...) key := append([]byte{blockedAccountPrefix}, hash.BytesBE()...)
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()
err := ic.DAO.PutStorageItem(p.ID, key, &state.StorageItem{ err := ic.DAO.PutStorageItem(p.ID, key, state.StorageItem{})
Value: []byte{},
})
if err != nil { if err != nil {
panic(err) panic(err)
} }

View file

@ -22,7 +22,7 @@ func getSerializableFromDAO(id int32, d dao.DAO, key []byte, item io.Serializabl
if si == nil { if si == nil {
return storage.ErrKeyNotFound return storage.ErrKeyNotFound
} }
r := io.NewBinReaderFromBuf(si.Value) r := io.NewBinReaderFromBuf(si)
item.DecodeBinary(r) item.DecodeBinary(r)
return r.Err return r.Err
} }
@ -33,9 +33,7 @@ func putSerializableToDAO(id int32, d dao.DAO, key []byte, item io.Serializable)
if w.Err != nil { if w.Err != nil {
return w.Err return w.Err
} }
return d.PutStorageItem(id, key, &state.StorageItem{ return d.PutStorageItem(id, key, w.Bytes())
Value: w.Bytes(),
})
} }
func getInt64WithKey(id int32, d dao.DAO, key []byte, defaultValue int64) int64 { func getInt64WithKey(id int32, d dao.DAO, key []byte, defaultValue int64) int64 {
@ -43,14 +41,12 @@ func getInt64WithKey(id int32, d dao.DAO, key []byte, defaultValue int64) int64
if si == nil { if si == nil {
return defaultValue return defaultValue
} }
return int64(binary.LittleEndian.Uint64(si.Value)) return int64(binary.LittleEndian.Uint64(si))
} }
func setInt64WithKey(id int32, dao dao.DAO, key []byte, value int64) error { func setInt64WithKey(id int32, dao dao.DAO, key []byte, value int64) error {
si := &state.StorageItem{ si := make(state.StorageItem, 8)
Value: make([]byte, 8), binary.LittleEndian.PutUint64(si, uint64(value))
}
binary.LittleEndian.PutUint64(si.Value, uint64(value))
return dao.PutStorageItem(id, key, si) return dao.PutStorageItem(id, key, si)
} }
@ -59,20 +55,17 @@ func getUint32WithKey(id int32, dao dao.DAO, key []byte, defaultValue uint32) ui
if si == nil { if si == nil {
return defaultValue return defaultValue
} }
return binary.LittleEndian.Uint32(si.Value) return binary.LittleEndian.Uint32(si)
} }
func setUint32WithKey(id int32, dao dao.DAO, key []byte, value uint32) error { func setUint32WithKey(id int32, dao dao.DAO, key []byte, value uint32) error {
si := &state.StorageItem{ si := make(state.StorageItem, 4)
Value: make([]byte, 4), binary.LittleEndian.PutUint32(si, value)
}
binary.LittleEndian.PutUint32(si.Value, value)
return dao.PutStorageItem(id, key, si) return dao.PutStorageItem(id, key, si)
} }
func setIntWithKey(id int32, dao dao.DAO, key []byte, value int64) error { func setIntWithKey(id int32, dao dao.DAO, key []byte, value int64) error {
si := &state.StorageItem{Value: bigint.ToBytes(big.NewInt(value))} return dao.PutStorageItem(id, key, bigint.ToBytes(big.NewInt(value)))
return dao.PutStorageItem(id, key, si)
} }
func getIntWithKey(id int32, dao dao.DAO, key []byte) int64 { func getIntWithKey(id int32, dao dao.DAO, key []byte) int64 {
@ -81,7 +74,7 @@ func getIntWithKey(id int32, dao dao.DAO, key []byte) int64 {
panic(fmt.Errorf("item with id = %d and key = %s is not initialized", id, hex.EncodeToString(key))) panic(fmt.Errorf("item with id = %d and key = %s is not initialized", id, hex.EncodeToString(key)))
} }
return bigint.FromBytes(si.Value).Int64() return bigint.FromBytes(si).Int64()
} }
// makeUint160Key creates a key from account script hash. // makeUint160Key creates a key from account script hash.

View file

@ -553,7 +553,7 @@ func TestContractDestroy(t *testing.T) {
cs1.Manifest.Permissions = []manifest.Permission{*manifest.NewPermission(manifest.PermissionWildcard)} cs1.Manifest.Permissions = []manifest.Permission{*manifest.NewPermission(manifest.PermissionWildcard)}
err := bc.contracts.Management.PutContractState(bc.dao, cs1) err := bc.contracts.Management.PutContractState(bc.dao, cs1)
require.NoError(t, err) require.NoError(t, err)
err = bc.dao.PutStorageItem(cs1.ID, []byte{1, 2, 3}, &state.StorageItem{Value: []byte{3, 2, 1}}) err = bc.dao.PutStorageItem(cs1.ID, []byte{1, 2, 3}, state.StorageItem{3, 2, 1})
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, bc.dao.UpdateMPT()) require.NoError(t, bc.dao.UpdateMPT())

View file

@ -180,7 +180,7 @@ func TestOracle_Request(t *testing.T) {
si := ic.DAO.GetStorageItem(cs.ID, []byte("lastOracleResponse")) si := ic.DAO.GetStorageItem(cs.ID, []byte("lastOracleResponse"))
require.NotNil(t, si) require.NotNil(t, si)
item, err := stackitem.DeserializeItem(si.Value) item, err := stackitem.DeserializeItem(si)
require.NoError(t, err) require.NoError(t, err)
arr, ok := item.Value().([]stackitem.Item) arr, ok := item.Value().([]stackitem.Item)
require.True(t, ok) require.True(t, ok)

View file

@ -5,16 +5,14 @@ import (
) )
// StorageItem is the value to be stored with read-only flag. // StorageItem is the value to be stored with read-only flag.
type StorageItem struct { type StorageItem []byte
Value []byte
}
// EncodeBinary implements Serializable interface. // EncodeBinary implements Serializable interface.
func (si *StorageItem) EncodeBinary(w *io.BinWriter) { func (si *StorageItem) EncodeBinary(w *io.BinWriter) {
w.WriteVarBytes(si.Value) w.WriteVarBytes(*si)
} }
// DecodeBinary implements Serializable interface. // DecodeBinary implements Serializable interface.
func (si *StorageItem) DecodeBinary(r *io.BinReader) { func (si *StorageItem) DecodeBinary(r *io.BinReader) {
si.Value = r.ReadVarBytes() *si = r.ReadVarBytes()
} }

View file

@ -7,9 +7,6 @@ import (
) )
func TestEncodeDecodeStorageItem(t *testing.T) { func TestEncodeDecodeStorageItem(t *testing.T) {
storageItem := &StorageItem{ storageItem := &StorageItem{1, 2, 3}
Value: []byte{1, 2, 3},
}
testserdes.EncodeDecodeBinary(t, storageItem, new(StorageItem)) testserdes.EncodeDecodeBinary(t, storageItem, new(StorageItem))
} }

View file

@ -868,7 +868,7 @@ func (s *Server) verifyProof(ps request.Params) (interface{}, *response.Error) {
if r.Err != nil { if r.Err != nil {
return nil, response.NewInternalServerError("invalid item in trie", r.Err) return nil, response.NewInternalServerError("invalid item in trie", r.Err)
} }
vp.Value = si.Value vp.Value = si
} }
return vp, nil return vp, nil
} }
@ -927,7 +927,7 @@ func (s *Server) getStorage(ps request.Params) (interface{}, *response.Error) {
return "", nil return "", nil
} }
return item.Value, nil return []byte(item), nil
} }
func (s *Server) getrawtransaction(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) getrawtransaction(reqParams request.Params) (interface{}, *response.Error) {