From 8cd7b93208f78815e4d3d323081719f4565bbbd3 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 8 Jul 2022 19:51:59 +0300 Subject: [PATCH] limits: new package with storage limits Packages like core/state or core/mpt shouldn't import whole core/storage just to get some constant value, it's not a good dependency. --- pkg/config/limits/limits.go | 17 +++++++++++++++++ pkg/core/blockchain.go | 3 ++- pkg/core/dao/dao.go | 3 ++- pkg/core/interop/storage/basic.go | 6 +++--- pkg/core/interop/storage/storage_test.go | 8 ++++---- pkg/core/mpt/extension.go | 4 ++-- pkg/core/mpt/leaf.go | 4 ++-- pkg/core/state/tokens.go | 4 ++-- pkg/core/storage/store.go | 8 -------- pkg/rpc/server/server.go | 4 ++-- 10 files changed, 36 insertions(+), 25 deletions(-) create mode 100644 pkg/config/limits/limits.go diff --git a/pkg/config/limits/limits.go b/pkg/config/limits/limits.go new file mode 100644 index 000000000..70c2368e3 --- /dev/null +++ b/pkg/config/limits/limits.go @@ -0,0 +1,17 @@ +/* +Package limits contains a number of system-wide hardcoded constants. +Many of the Neo protocol parameters can be adjusted by the configuration, but +some can not and this package contains hardcoded limits that are relevant for +many applications. +*/ +package limits + +const ( + // MaxStorageKeyLen is the maximum length of a key for storage items. + // Contracts can't use keys longer than that in their requests to the DB. + MaxStorageKeyLen = 64 + // MaxStorageValueLen is the maximum length of a value for storage items. + // It is set to be the maximum value for uint16, contracts can't put + // values longer than that into the DB. + MaxStorageValueLen = 65535 +) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index e1ddea8ac..366ea38b4 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -13,6 +13,7 @@ import ( "time" "github.com/nspcc-dev/neo-go/pkg/config" + "github.com/nspcc-dev/neo-go/pkg/config/limits" "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/blockchainer/services" @@ -1328,7 +1329,7 @@ func (bc *Blockchain) handleNotification(note *state.NotificationEvent, d *dao.S var id []byte if len(arr) == 4 { id, err = arr[3].TryBytes() - if err != nil || len(id) > storage.MaxStorageKeyLen { + if err != nil || len(id) > limits.MaxStorageKeyLen { return } } diff --git a/pkg/core/dao/dao.go b/pkg/core/dao/dao.go index c2563f24d..b9f8ced9d 100644 --- a/pkg/core/dao/dao.go +++ b/pkg/core/dao/dao.go @@ -10,6 +10,7 @@ import ( "math/big" "sync" + "github.com/nspcc-dev/neo-go/pkg/config/limits" "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/storage" @@ -830,7 +831,7 @@ func (dao *Simple) StoreAsTransaction(tx *transaction.Transaction, index uint32, func (dao *Simple) getKeyBuf(len int) []byte { if dao.private { if dao.keyBuf == nil { - dao.keyBuf = make([]byte, 0, 1+4+storage.MaxStorageKeyLen) // Prefix, uint32, key. + dao.keyBuf = make([]byte, 0, 1+4+limits.MaxStorageKeyLen) // Prefix, uint32, key. } return dao.keyBuf[:len] // Should have enough capacity. } diff --git a/pkg/core/interop/storage/basic.go b/pkg/core/interop/storage/basic.go index dcb6771c8..a3cd1db63 100644 --- a/pkg/core/interop/storage/basic.go +++ b/pkg/core/interop/storage/basic.go @@ -4,8 +4,8 @@ import ( "errors" "fmt" + "github.com/nspcc-dev/neo-go/pkg/config/limits" "github.com/nspcc-dev/neo-go/pkg/core/interop" - "github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) @@ -81,10 +81,10 @@ func getContextInternal(ic *interop.Context, isReadOnly bool) error { } func putWithContext(ic *interop.Context, stc *Context, key []byte, value []byte) error { - if len(key) > storage.MaxStorageKeyLen { + if len(key) > limits.MaxStorageKeyLen { return errors.New("key is too big") } - if len(value) > storage.MaxStorageValueLen { + if len(value) > limits.MaxStorageValueLen { return errors.New("value is too big") } if stc.ReadOnly { diff --git a/pkg/core/interop/storage/storage_test.go b/pkg/core/interop/storage/storage_test.go index 7cfa53a74..7fa0f6f04 100644 --- a/pkg/core/interop/storage/storage_test.go +++ b/pkg/core/interop/storage/storage_test.go @@ -5,6 +5,7 @@ import ( "math/big" "testing" + "github.com/nspcc-dev/neo-go/pkg/config/limits" "github.com/nspcc-dev/neo-go/pkg/core" "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/interop" @@ -12,7 +13,6 @@ import ( istorage "github.com/nspcc-dev/neo-go/pkg/core/interop/storage" "github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/state" - "github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/neotest/chain" @@ -61,7 +61,7 @@ func TestPut(t *testing.T) { }) t.Run("check limits", func(t *testing.T) { - initVM(t, make([]byte, storage.MaxStorageKeyLen), make([]byte, storage.MaxStorageValueLen), -1) + initVM(t, make([]byte, limits.MaxStorageKeyLen), make([]byte, limits.MaxStorageValueLen), -1) require.NoError(t, istorage.Put(ic)) }) @@ -72,11 +72,11 @@ func TestPut(t *testing.T) { require.Error(t, istorage.Put(ic)) }) t.Run("big key", func(t *testing.T) { - initVM(t, make([]byte, storage.MaxStorageKeyLen+1), []byte{1}, -1) + initVM(t, make([]byte, limits.MaxStorageKeyLen+1), []byte{1}, -1) require.Error(t, istorage.Put(ic)) }) t.Run("big value", func(t *testing.T) { - initVM(t, []byte{1}, make([]byte, storage.MaxStorageValueLen+1), -1) + initVM(t, []byte{1}, make([]byte, limits.MaxStorageValueLen+1), -1) require.Error(t, istorage.Put(ic)) }) }) diff --git a/pkg/core/mpt/extension.go b/pkg/core/mpt/extension.go index 518cc2787..49af8558b 100644 --- a/pkg/core/mpt/extension.go +++ b/pkg/core/mpt/extension.go @@ -6,14 +6,14 @@ import ( "errors" "fmt" - "github.com/nspcc-dev/neo-go/pkg/core/storage" + "github.com/nspcc-dev/neo-go/pkg/config/limits" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/util" ) const ( // maxPathLength is the max length of the extension node key. - maxPathLength = (storage.MaxStorageKeyLen + 4) * 2 + maxPathLength = (limits.MaxStorageKeyLen + 4) * 2 // MaxKeyLength is the max length of the key to put in the trie // before transforming to nibbles. diff --git a/pkg/core/mpt/leaf.go b/pkg/core/mpt/leaf.go index ce3f36f22..0da66f24f 100644 --- a/pkg/core/mpt/leaf.go +++ b/pkg/core/mpt/leaf.go @@ -5,13 +5,13 @@ import ( "errors" "fmt" - "github.com/nspcc-dev/neo-go/pkg/core/storage" + "github.com/nspcc-dev/neo-go/pkg/config/limits" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/util" ) // MaxValueLength is the max length of a leaf node value. -const MaxValueLength = 3 + storage.MaxStorageValueLen + 1 +const MaxValueLength = 3 + limits.MaxStorageValueLen + 1 // LeafNode represents an MPT's leaf node. type LeafNode struct { diff --git a/pkg/core/state/tokens.go b/pkg/core/state/tokens.go index 81739ccdf..63a64f0d2 100644 --- a/pkg/core/state/tokens.go +++ b/pkg/core/state/tokens.go @@ -4,7 +4,7 @@ import ( "bytes" "math/big" - "github.com/nspcc-dev/neo-go/pkg/core/storage" + "github.com/nspcc-dev/neo-go/pkg/config/limits" "github.com/nspcc-dev/neo-go/pkg/encoding/bigint" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/util" @@ -224,5 +224,5 @@ func (t *NEP11Transfer) EncodeBinary(w *io.BinWriter) { // DecodeBinary implements the io.Serializable interface. func (t *NEP11Transfer) DecodeBinary(r *io.BinReader) { t.NEP17Transfer.DecodeBinary(r) - t.ID = r.ReadVarBytes(storage.MaxStorageKeyLen) + t.ID = r.ReadVarBytes(limits.MaxStorageKeyLen) } diff --git a/pkg/core/storage/store.go b/pkg/core/storage/store.go index 3e2ef4c89..785e47886 100644 --- a/pkg/core/storage/store.go +++ b/pkg/core/storage/store.go @@ -41,14 +41,6 @@ const ( ExecTransaction byte = 2 ) -const ( - // MaxStorageKeyLen is the maximum length of a key for storage items. - MaxStorageKeyLen = 64 - // MaxStorageValueLen is the maximum length of a value for storage items. - // It is set to be the maximum value for uint16. - MaxStorageValueLen = 65535 -) - // Operation represents a single KV operation (add/del/change) performed // in the DB. type Operation struct { diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 8ecd24be4..0e0b86e47 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -20,6 +20,7 @@ import ( "github.com/google/uuid" "github.com/gorilla/websocket" + "github.com/nspcc-dev/neo-go/pkg/config/limits" "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core" "github.com/nspcc-dev/neo-go/pkg/core/block" @@ -31,7 +32,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/mpt" "github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/state" - "github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" @@ -846,7 +846,7 @@ contract_loop: curAsset := &bs.Balances[len(bs.Balances)-1] for i := range toks { id, err := toks[i].TryBytes() - if err != nil || len(id) > storage.MaxStorageKeyLen { + if err != nil || len(id) > limits.MaxStorageKeyLen { continue } var amount = "1"