Skip to content

Commit

Permalink
Merge pull request #1250 from CityOfZion/CU-86drpne63
Browse files Browse the repository at this point in the history
#86drpne63 - Add new methods on storage to get/put arrays, maps and objects without the need of stdlib convertion
  • Loading branch information
luc10921 authored May 10, 2024
2 parents 95775e7 + 8e679cd commit 581571c
Show file tree
Hide file tree
Showing 24 changed files with 656 additions and 29 deletions.
211 changes: 209 additions & 2 deletions boa3/builtin/interop/storage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@
'get_int',
'get_bool',
'get_str',
'get_list',
'get_dict',
'get_object',
'get_uint160',
'get_uint256',
'get_ecpoint',
'try_get',
'try_get_int',
'try_get_bool',
'try_get_str',
'try_get_list',
'try_get_dict',
'try_get_object',
'try_get_uint160',
'try_get_uint256',
'try_get_ecpoint',
Expand All @@ -22,13 +28,18 @@
'put_int',
'put_bool',
'put_str',
'put_list',
'put_dict',
'put_object',
'put_uint160',
'put_uint256',
'put_ecpoint',
'delete',
'find',
]

from typing import Any

from deprecation import deprecated

from boa3.builtin.interop.iterator import Iterator
Expand Down Expand Up @@ -57,7 +68,7 @@ def get(key: bytes, context: StorageContext = get_context()) -> bytes:
"""
Gets a value from the persistent store based on the given key.
>>> put(b'unit', 'test')
>>> put(b'unit', b'test')
... get(b'unit')
b'test'
Expand All @@ -79,7 +90,7 @@ def try_get(key: bytes, context: StorageContext = get_context()) -> tuple[bytes,
"""
Gets a value from the persistent store based on the given key and returns whether the value is stored.
>>> put(b'unit', 'test')
>>> put(b'unit', b'test')
... try_get(b'unit')
(b'test', True)
Expand Down Expand Up @@ -231,6 +242,144 @@ def try_get_str(key: bytes, context: StorageContext = get_context()) -> tuple[st
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_list(key: bytes, context: StorageContext = get_context()) -> list:
"""
Gets a value as list from the persistent store based on the given key.
It's equivalent to boa3.builtin.nativecontract.stdlib.StdLib.deserialize(get(key, context))
>>> put_list(b'unit', [1, 2, '3'])
... get_list(b'unit')
[1, 2, '3']
>>> get_list(b'fake_key')
[]
:param key: value identifier in the store
:type key: bytes
:param context: storage context to be used
:type context: StorageContext
:return: the value corresponding to given key for current storage context
:rtype: list
"""
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def try_get_list(key: bytes, context: StorageContext = get_context()) -> tuple[list, bool]:
"""
Gets a value as list from the persistent store based on the given key and returns whether the value is stored.
>>> put_list(b'unit', [1, 2, '3'])
... try_get_list(b'unit')
([1, 2, '3'], True)
>>> get_list(b'fake_key')
([], False)
:param key: value identifier in the store
:type key: bytes
:param context: storage context to be used
:type context: StorageContext
:return: the value corresponding to given key for current storage context and whether it was actually stored
:rtype: tuple[list, bool]
"""
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_dict(key: bytes, context: StorageContext = get_context()) -> dict:
"""
Gets a value as dict from the persistent store based on the given key.
It's equivalent to boa3.builtin.nativecontract.stdlib.StdLib.deserialize(get(key, context))
>>> put_dict(b'unit', {'example': 1, 'other_example': 2})
... get_dict(b'unit')
{'example': 1, 'other_example': 2}
>>> get_dict(b'fake_key')
{}
:param key: value identifier in the store
:type key: bytes
:param context: storage context to be used
:type context: StorageContext
:return: the value corresponding to given key for current storage context
:rtype: dict
"""
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def try_get_dict(key: bytes, context: StorageContext = get_context()) -> tuple[dict, bool]:
"""
Gets a value as dict from the persistent store based on the given key and returns whether the value is stored.
>>> put_dict(b'unit', {'example': 1, 'other_example': 2})
... get_dict(b'unit')
({'example': 1, 'other_example': 2}, True)
>>> get_dict(b'fake_key')
({}, False)
:param key: value identifier in the store
:type key: bytes
:param context: storage context to be used
:type context: StorageContext
:return: the value corresponding to given key for current storage context and whether it was actually stored
:rtype: tuple[dict, bool]
"""
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_object(key: bytes, context: StorageContext = get_context()) -> Any:
"""
Gets a value as object from the persistent store based on the given key.
It's equivalent to boa3.builtin.nativecontract.stdlib.StdLib.deserialize(get(key, context))
Returns an empty struct if not found.
>>> example = SomeClass()
>>> put_object(b'unit', example)
... get_object(b'unit')
SomeClass
>>> get_object(b'fake_key')
object
:param key: value identifier in the store
:type key: bytes
:param context: storage context to be used
:type context: StorageContext
:return: the value corresponding to given key for current storage context
:rtype: Any
"""
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def try_get_object(key: bytes, context: StorageContext = get_context()) -> tuple[Any, bool]:
"""
Gets a value as dict from the persistent store based on the given key and returns whether the value is stored.
>>> example = SomeClass()
>>> put_object(b'unit', example)
... try_get_object(b'unit')
(SomeClass, True)
>>> get_object(b'fake_key')
(object, False)
:param key: value identifier in the store
:type key: bytes
:param context: storage context to be used
:type context: StorageContext
:return: the value corresponding to given key for current storage context and whether it was actually stored
:rtype: tuple[Any, bool]
"""
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def get_uint160(key: bytes, context: StorageContext = get_context()) -> UInt160:
"""
Expand Down Expand Up @@ -455,6 +604,64 @@ def put_str(key: bytes, value: str, context: StorageContext = get_context()):
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def put_list(key: bytes, value: list, context: StorageContext = get_context()):
"""
Inserts a given list value in the key-value format into the persistent storage.
It's equivalent to put(key, boa3.builtin.nativecontract.stdlib.serialize(value), context)
>>> put_list(b'unit', [1, 2, '3'])
None
:param key: the identifier in the store for the new value
:type key: bytes
:param value: value to be stored
:type value: list
:param context: storage context to be used
:type context: StorageContext
"""
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def put_dict(key: bytes, value: dict, context: StorageContext = get_context()):
"""
Inserts a given dict value in the key-value format into the persistent storage.
It's equivalent to put(key, boa3.builtin.nativecontract.stdlib.serialize(value), context)
>>> put_dict(b'unit', {'example': 1, 'other_example': 2})
None
:param key: the identifier in the store for the new value
:type key: bytes
:param value: value to be stored
:type value: dict
:param context: storage context to be used
:type context: StorageContext
"""
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def put_object(key: bytes, value: object, context: StorageContext = get_context()):
"""
Inserts a given object value in the key-value format into the persistent storage.
It's equivalent to put(key, boa3.builtin.nativecontract.stdlib.serialize(value), context)
>>> example = SomeClass()
>>> put_object(b'unit', example)
None
:param key: the identifier in the store for the new value
:type key: bytes
:param value: value to be stored
:type value: dict
:param context: storage context to be used
:type context: StorageContext
"""
pass


@deprecated(details='This module is deprecated. Use boa3.sc.storage instead')
def put_uint160(key: bytes, value: UInt160, context: StorageContext = get_context()):
"""
Expand Down
7 changes: 4 additions & 3 deletions boa3/internal/compiler/codegenerator/codegenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1202,19 +1202,20 @@ def convert_new_map(self, map_type: IType):
self.__insert1(OpcodeInfo.NEWMAP)
self._stack_append(map_type)

def convert_new_empty_array(self, length: int, array_type: IType):
def convert_new_empty_array(self, length: int, array_type: IType, *, as_struct: bool = False):
"""
Converts the creation of a new empty array
:param length: the size of the new array
:param array_type: the Neo Boa type of the array
:param as_struct: convert as struct instead of array
"""
if length <= 0:
self.__insert1(OpcodeInfo.NEWARRAY0)
self.__insert1(OpcodeInfo.NEWARRAY0 if not as_struct else OpcodeInfo.NEWSTRUCT0)
else:
self.convert_literal(length)
self._stack_pop()
self.__insert1(OpcodeInfo.NEWARRAY)
self.__insert1(OpcodeInfo.NEWARRAY if not as_struct else OpcodeInfo.NEWSTRUCT)
self._stack_append(array_type)

def convert_new_array(self, length: int, array_type: IType = Type.list):
Expand Down
18 changes: 18 additions & 0 deletions boa3/internal/model/builtin/interop/interop.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,20 +196,29 @@ def interop_events(cls) -> list[Event]:
StorageGetInt = StorageGetIntMethod()
StorageGetBool = StorageGetBoolMethod()
StorageGetStr = StorageGetStrMethod()
StorageGetList = StorageGetListMethod()
StorageGetDict = StorageGetDictMethod()
StorageGetObject = StorageGetObjectMethod()
StorageGetUInt160 = StorageGetUInt160Method()
StorageGetUInt256 = StorageGetUInt256Method()
StorageGetECPoint = StorageGetECPointMethod()
StorageGetCheck = StorageTryGetBytesMethod()
StorageGetCheckInt = StorageTryGetIntMethod()
StorageGetCheckBool = StorageTryGetBoolMethod()
StorageGetCheckStr = StorageTryGetStrMethod()
StorageGetCheckList = StorageTryGetListMethod()
StorageGetCheckDict = StorageTryGetDictMethod()
StorageGetCheckObject = StorageTryGetObjectMethod()
StorageGetCheckUInt160 = StorageTryGetUInt160Method()
StorageGetCheckUInt256 = StorageTryGetUInt256Method()
StorageGetCheckECPoint = StorageTryGetECPointMethod()
StoragePut = StoragePutBytesMethod()
StoragePutInt = StoragePutIntMethod()
StoragePutBool = StoragePutBoolMethod()
StoragePutStr = StoragePutStrMethod()
StoragePutList = StoragePutListMethod()
StoragePutDict = StoragePutDictMethod()
StoragePutObject = StoragePutObjectMethod()
StoragePutUInt160 = StoragePutUInt160Method()
StoragePutUInt256 = StoragePutUInt256Method()
StoragePutECPoint = StoragePutECPointMethod()
Expand Down Expand Up @@ -457,13 +466,19 @@ def interop_events(cls) -> list[Event]:
StorageGetInt,
StorageGetBool,
StorageGetStr,
StorageGetList,
StorageGetDict,
StorageGetObject,
StorageGetUInt160,
StorageGetUInt256,
StorageGetECPoint,
StorageGetCheck,
StorageGetCheckInt,
StorageGetCheckBool,
StorageGetCheckStr,
StorageGetCheckList,
StorageGetCheckDict,
StorageGetCheckObject,
StorageGetCheckUInt160,
StorageGetCheckUInt256,
StorageGetCheckECPoint,
Expand All @@ -473,6 +488,9 @@ def interop_events(cls) -> list[Event]:
StoragePutInt,
StoragePutBool,
StoragePutStr,
StoragePutList,
StoragePutDict,
StoragePutObject,
StoragePutUInt160,
StoragePutUInt256,
StoragePutECPoint,
Expand Down
9 changes: 9 additions & 0 deletions boa3/internal/model/builtin/interop/storage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,32 @@
'StorageGetReadOnlyContextMethod',
'StorageGetBoolMethod',
'StorageGetBytesMethod',
'StorageGetDictMethod',
'StorageGetECPointMethod',
'StorageGetIntMethod',
'StorageGetListMethod',
'StorageGetObjectMethod',
'StorageGetStrMethod',
'StorageGetUInt160Method',
'StorageGetUInt256Method',
'StorageMapType',
'StoragePutBoolMethod',
'StoragePutBytesMethod',
'StoragePutDictMethod',
'StoragePutECPointMethod',
'StoragePutIntMethod',
'StoragePutListMethod',
'StoragePutObjectMethod',
'StoragePutStrMethod',
'StoragePutUInt160Method',
'StoragePutUInt256Method',
'StorageTryGetBoolMethod',
'StorageTryGetBytesMethod',
'StorageTryGetDictMethod',
'StorageTryGetECPointMethod',
'StorageTryGetIntMethod',
'StorageTryGetListMethod',
'StorageTryGetObjectMethod',
'StorageTryGetStrMethod',
'StorageTryGetUInt160Method',
'StorageTryGetUInt256Method',
Expand Down
3 changes: 3 additions & 0 deletions boa3/internal/model/builtin/interop/storage/get/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from boa3.internal.model.builtin.interop.storage.get.storagegetboolmethod import StorageGetBoolMethod
from boa3.internal.model.builtin.interop.storage.get.storagegetbytesmethod import StorageGetBytesMethod
from boa3.internal.model.builtin.interop.storage.get.storagegetdictmethod import StorageGetDictMethod
from boa3.internal.model.builtin.interop.storage.get.storagegetecpointmethod import StorageGetECPointMethod
from boa3.internal.model.builtin.interop.storage.get.storagegetintmethod import StorageGetIntMethod
from boa3.internal.model.builtin.interop.storage.get.storagegetlistmethod import StorageGetListMethod
from boa3.internal.model.builtin.interop.storage.get.storagegetobjectmethod import StorageGetObjectMethod
from boa3.internal.model.builtin.interop.storage.get.storagegetstrmethod import StorageGetStrMethod
from boa3.internal.model.builtin.interop.storage.get.storagegetuint160method import StorageGetUInt160Method
from boa3.internal.model.builtin.interop.storage.get.storagegetuint256method import StorageGetUInt256Method
Loading

0 comments on commit 581571c

Please sign in to comment.