core/state: remove IsConst
from StorageItem
This commit is contained in:
parent
df041b8031
commit
fd4174ad31
10 changed files with 10 additions and 86 deletions
|
@ -98,7 +98,6 @@ func TestSyscallExecution(t *testing.T) {
|
|||
"storage.GetContext": {interopnames.SystemStorageGetContext, nil, false},
|
||||
"storage.GetReadOnlyContext": {interopnames.SystemStorageGetReadOnlyContext, nil, false},
|
||||
"storage.Put": {interopnames.SystemStoragePut, []string{sctx, b, b}, true},
|
||||
"storage.PutEx": {interopnames.SystemStoragePutEx, []string{sctx, b, b, "storage.PutConstant"}, true},
|
||||
"storage.ConvertContextToReadOnly": {interopnames.SystemStorageAsReadOnly, []string{sctx}, false},
|
||||
"crypto.ECDsaSecp256r1Verify": {interopnames.NeoCryptoVerifyWithECDsaSecp256r1, []string{b, pub, sig}, false},
|
||||
"crypto.ECDsaSecp256k1Verify": {interopnames.NeoCryptoVerifyWithECDsaSecp256k1, []string{b, pub, sig}, false},
|
||||
|
|
|
@ -46,7 +46,6 @@ const (
|
|||
SystemStorageGetContext = "System.Storage.GetContext"
|
||||
SystemStorageGetReadOnlyContext = "System.Storage.GetReadOnlyContext"
|
||||
SystemStoragePut = "System.Storage.Put"
|
||||
SystemStoragePutEx = "System.Storage.PutEx"
|
||||
SystemStorageAsReadOnly = "System.Storage.AsReadOnly"
|
||||
NeoCryptoVerifyWithECDsaSecp256r1 = "Neo.Crypto.VerifyWithECDsaSecp256r1"
|
||||
NeoCryptoVerifyWithECDsaSecp256k1 = "Neo.Crypto.VerifyWithECDsaSecp256k1"
|
||||
|
@ -101,7 +100,6 @@ var names = []string{
|
|||
SystemStorageGetContext,
|
||||
SystemStorageGetReadOnlyContext,
|
||||
SystemStoragePut,
|
||||
SystemStoragePutEx,
|
||||
SystemStorageAsReadOnly,
|
||||
NeoCryptoVerifyWithECDsaSecp256r1,
|
||||
NeoCryptoVerifyWithECDsaSecp256k1,
|
||||
|
|
|
@ -73,10 +73,6 @@ func storageDelete(ic *interop.Context) error {
|
|||
}
|
||||
ic.VM.AddGas(ic.Chain.GetPolicer().GetStoragePrice())
|
||||
key := ic.VM.Estack().Pop().Bytes()
|
||||
si := ic.DAO.GetStorageItem(stc.ID, key)
|
||||
if si != nil && si.IsConst {
|
||||
return errors.New("storage item is constant")
|
||||
}
|
||||
return ic.DAO.DeleteStorageItem(stc.ID, key)
|
||||
}
|
||||
|
||||
|
@ -122,7 +118,7 @@ func storageGetContextInternal(ic *interop.Context, isReadOnly bool) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func putWithContextAndFlags(ic *interop.Context, stc *StorageContext, key []byte, value []byte, isConst bool) error {
|
||||
func putWithContext(ic *interop.Context, stc *StorageContext, key []byte, value []byte) error {
|
||||
if len(key) > MaxStorageKeyLen {
|
||||
return errors.New("key is too big")
|
||||
}
|
||||
|
@ -133,17 +129,14 @@ func putWithContextAndFlags(ic *interop.Context, stc *StorageContext, key []byte
|
|||
return errors.New("StorageContext is read only")
|
||||
}
|
||||
si := ic.DAO.GetStorageItem(stc.ID, key)
|
||||
if si != nil && si.IsConst {
|
||||
return errors.New("storage item exists and is read-only")
|
||||
}
|
||||
sizeInc := 1
|
||||
sizeInc := len(value)
|
||||
if si == nil {
|
||||
si = &state.StorageItem{}
|
||||
sizeInc = len(key) + len(value)
|
||||
} else if len(value) != 0 {
|
||||
if len(value) <= len(si.Value) {
|
||||
sizeInc = (len(value)-1)/4 + 1
|
||||
} else {
|
||||
} else if len(si.Value) != 0 {
|
||||
sizeInc = (len(si.Value)-1)/4 + 1 + len(value) - len(si.Value)
|
||||
}
|
||||
}
|
||||
|
@ -151,12 +144,11 @@ func putWithContextAndFlags(ic *interop.Context, stc *StorageContext, key []byte
|
|||
return errGasLimitExceeded
|
||||
}
|
||||
si.Value = value
|
||||
si.IsConst = isConst
|
||||
return ic.DAO.PutStorageItem(stc.ID, key, si)
|
||||
}
|
||||
|
||||
// storagePutInternal is a unified implementation of storagePut and storagePutEx.
|
||||
func storagePutInternal(ic *interop.Context, getFlag bool) error {
|
||||
// storagePut puts key-value pair into the storage.
|
||||
func storagePut(ic *interop.Context) error {
|
||||
stcInterface := ic.VM.Estack().Pop().Value()
|
||||
stc, ok := stcInterface.(*StorageContext)
|
||||
if !ok {
|
||||
|
@ -164,21 +156,7 @@ func storagePutInternal(ic *interop.Context, getFlag bool) error {
|
|||
}
|
||||
key := ic.VM.Estack().Pop().Bytes()
|
||||
value := ic.VM.Estack().Pop().Bytes()
|
||||
var flag int
|
||||
if getFlag {
|
||||
flag = int(ic.VM.Estack().Pop().BigInt().Int64())
|
||||
}
|
||||
return putWithContextAndFlags(ic, stc, key, value, int(Constant)&flag != 0)
|
||||
}
|
||||
|
||||
// storagePut puts key-value pair into the storage.
|
||||
func storagePut(ic *interop.Context) error {
|
||||
return storagePutInternal(ic, false)
|
||||
}
|
||||
|
||||
// storagePutEx puts key-value pair with given flags into the storage.
|
||||
func storagePutEx(ic *interop.Context) error {
|
||||
return storagePutInternal(ic, true)
|
||||
return putWithContext(ic, stc, key, value)
|
||||
}
|
||||
|
||||
// storageContextAsReadOnly sets given context to read-only mode.
|
||||
|
|
|
@ -277,21 +277,6 @@ func TestStoragePut(t *testing.T) {
|
|||
initVM(t, []byte{1}, make([]byte, MaxStorageValueLen+1), -1)
|
||||
require.Error(t, storagePut(ic))
|
||||
})
|
||||
t.Run("item exists and is const", func(t *testing.T) {
|
||||
v := ic.SpawnVM()
|
||||
v.LoadScript(cs.NEF.Script)
|
||||
v.GasLimit = -1
|
||||
v.Estack().PushVal(1)
|
||||
v.Estack().PushVal("value")
|
||||
v.Estack().PushVal("key")
|
||||
require.NoError(t, storageGetContext(ic))
|
||||
require.NoError(t, storagePutEx(ic))
|
||||
|
||||
v.Estack().PushVal("new")
|
||||
v.Estack().PushVal("key")
|
||||
require.NoError(t, storageGetContext(ic))
|
||||
require.Error(t, storagePut(ic))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -301,16 +286,14 @@ func TestStorageDelete(t *testing.T) {
|
|||
require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, cs))
|
||||
v.LoadScriptWithHash(cs.NEF.Script, cs.Hash, callflag.All)
|
||||
put := func(key, value string, flag int) {
|
||||
v.Estack().PushVal(flag)
|
||||
v.Estack().PushVal(value)
|
||||
v.Estack().PushVal(key)
|
||||
require.NoError(t, storageGetContext(ic))
|
||||
require.NoError(t, storagePutEx(ic))
|
||||
require.NoError(t, storagePut(ic))
|
||||
}
|
||||
put("key1", "value1", 0)
|
||||
put("key2", "value2", 0)
|
||||
put("key3", "value3", 0)
|
||||
put("key4", "value4", 1)
|
||||
|
||||
t.Run("good", func(t *testing.T) {
|
||||
v.Estack().PushVal("key1")
|
||||
|
@ -328,11 +311,6 @@ func TestStorageDelete(t *testing.T) {
|
|||
require.NoError(t, storageContextAsReadOnly(ic))
|
||||
require.Error(t, storageDelete(ic))
|
||||
})
|
||||
t.Run("constant item", func(t *testing.T) {
|
||||
v.Estack().PushVal("key4")
|
||||
require.NoError(t, storageGetContext(ic))
|
||||
require.Error(t, storageDelete(ic))
|
||||
})
|
||||
}
|
||||
|
||||
// getTestContractState returns 2 contracts second of which is allowed to call the first.
|
||||
|
|
|
@ -82,8 +82,6 @@ var systemInterops = []interop.Function{
|
|||
RequiredFlags: callflag.ReadStates},
|
||||
{Name: interopnames.SystemStoragePut, Func: storagePut, Price: 0, RequiredFlags: callflag.WriteStates,
|
||||
ParamCount: 3}, // These don't have static price in C# code.
|
||||
{Name: interopnames.SystemStoragePutEx, Func: storagePutEx, Price: 0, RequiredFlags: callflag.WriteStates,
|
||||
ParamCount: 4},
|
||||
{Name: interopnames.SystemStorageAsReadOnly, Func: storageContextAsReadOnly, Price: 1 << 4,
|
||||
RequiredFlags: callflag.ReadStates, ParamCount: 1},
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ func TestUnexpectedNonInterops(t *testing.T) {
|
|||
storageFind,
|
||||
storageGet,
|
||||
storagePut,
|
||||
storagePutEx,
|
||||
}
|
||||
for _, f := range funcs {
|
||||
for k, v := range vals {
|
||||
|
|
|
@ -926,9 +926,6 @@ func (n *NEO) putGASRecord(dao dao.DAO, index uint32, value *big.Int) error {
|
|||
key := make([]byte, 5)
|
||||
key[0] = prefixGASPerBlock
|
||||
binary.BigEndian.PutUint32(key[1:], index)
|
||||
si := &state.StorageItem{
|
||||
Value: bigint.ToBytes(value),
|
||||
IsConst: false,
|
||||
}
|
||||
si := &state.StorageItem{Value: bigint.ToBytes(value)}
|
||||
return dao.PutStorageItem(n.ID, key, si)
|
||||
}
|
||||
|
|
|
@ -6,18 +6,15 @@ import (
|
|||
|
||||
// StorageItem is the value to be stored with read-only flag.
|
||||
type StorageItem struct {
|
||||
Value []byte
|
||||
IsConst bool
|
||||
Value []byte
|
||||
}
|
||||
|
||||
// EncodeBinary implements Serializable interface.
|
||||
func (si *StorageItem) EncodeBinary(w *io.BinWriter) {
|
||||
w.WriteVarBytes(si.Value)
|
||||
w.WriteBool(si.IsConst)
|
||||
}
|
||||
|
||||
// DecodeBinary implements Serializable interface.
|
||||
func (si *StorageItem) DecodeBinary(r *io.BinReader) {
|
||||
si.Value = r.ReadVarBytes()
|
||||
si.IsConst = r.ReadBool()
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ import (
|
|||
|
||||
func TestEncodeDecodeStorageItem(t *testing.T) {
|
||||
storageItem := &StorageItem{
|
||||
Value: []byte{},
|
||||
IsConst: false,
|
||||
Value: []byte{1, 2, 3},
|
||||
}
|
||||
|
||||
testserdes.EncodeDecodeBinary(t, storageItem, new(StorageItem))
|
||||
|
|
|
@ -38,16 +38,6 @@ const (
|
|||
PickField1 FindFlags = 1 << 5
|
||||
)
|
||||
|
||||
// PutFlags represents flag of `PutEx` syscall.
|
||||
type PutFlags byte
|
||||
|
||||
const (
|
||||
// PutDefault is a storage flag for non-constant items.
|
||||
PutDefault PutFlags = 0
|
||||
// PutConstant is a storage flag for constant items.
|
||||
PutConstant PutFlags = 0x01
|
||||
)
|
||||
|
||||
// ConvertContextToReadOnly returns new context from the given one, but with
|
||||
// writing capability turned off, so that you could only invoke Get and Find
|
||||
// using this new Context. If Context is already read-only this function is a
|
||||
|
@ -79,15 +69,6 @@ func Put(ctx Context, key interface{}, value interface{}) {
|
|||
neogointernal.Syscall3NoReturn("System.Storage.Put", ctx, key, value)
|
||||
}
|
||||
|
||||
// PutEx is an advanced version of Put which saves given value with given key
|
||||
// and given ReadOnly flag in the storage using given Context. `flag` argument
|
||||
// can either be odd for constant storage items or even for variable storage items.
|
||||
// Refer to Put function description for details on how to pass the remaining
|
||||
// arguments. This function uses `System.Storage.PutEx` syscall.
|
||||
func PutEx(ctx Context, key interface{}, value interface{}, flag PutFlags) {
|
||||
neogointernal.Syscall4NoReturn("System.Storage.PutEx", ctx, key, value, flag)
|
||||
}
|
||||
|
||||
// Get retrieves value stored for the given key using given Context. See Put
|
||||
// documentation on possible key and value types. If the value is not present in
|
||||
// the database it returns nil. This function uses `System.Storage.Get` syscall.
|
||||
|
|
Loading…
Reference in a new issue