Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#86dthh0zp - Update native PolicyContract #1254

Merged
merged 1 commit into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions boa3/internal/model/builtin/interop/interop.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def interop_events(cls) -> list[Event]:
StorageContextType = StorageContextType.build()
StorageMapType = StorageMapType.build()
TransactionType = TransactionType.build()
TransactionAttributeType = TransactionAttributeType()
TriggerType = TriggerType()
VMStateType = VMStateType.build()
WitnessCondition = WitnessConditionType.build()
Expand Down Expand Up @@ -148,7 +149,9 @@ def interop_events(cls) -> list[Event]:
GetExecFeeFactor = GetExecFeeFactorMethod()
GetFeePerByte = GetFeePerByteMethod()
GetStoragePrice = GetStoragePriceMethod()
GetAttributeFee = GetAttributeFeeMethod(TransactionAttributeType)
IsBlocked = IsBlockedMethod()
SetAttributeFee = SetAttributeFeeMethod(TransactionAttributeType)

# Role Interops
GetDesignatedByRole = GetDesignatedByRoleMethod()
Expand Down
17 changes: 12 additions & 5 deletions boa3/internal/model/builtin/interop/policy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
__all__ = ['GetExecFeeFactorMethod',
'GetFeePerByteMethod',
'GetStoragePriceMethod',
'IsBlockedMethod'
]
__all__ = [
'GetAttributeFeeMethod',
'GetExecFeeFactorMethod',
'GetFeePerByteMethod',
'GetStoragePriceMethod',
'IsBlockedMethod',
'SetAttributeFeeMethod',
'TransactionAttributeType',
]

from boa3.internal.model.builtin.interop.policy.getattributefeemethod import GetAttributeFeeMethod
from boa3.internal.model.builtin.interop.policy.getexecfeefactormethod import GetExecFeeFactorMethod
from boa3.internal.model.builtin.interop.policy.getfeeperbytemethod import GetFeePerByteMethod
from boa3.internal.model.builtin.interop.policy.getstoragepricemethod import GetStoragePriceMethod
from boa3.internal.model.builtin.interop.policy.isblockedmethod import IsBlockedMethod
from boa3.internal.model.builtin.interop.policy.setattributefeemethod import SetAttributeFeeMethod
from boa3.internal.model.builtin.interop.policy.transactionattributetype import TransactionAttributeType
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from boa3.internal.model.builtin.interop.nativecontract import PolicyContractMethod
from boa3.internal.model.builtin.interop.policy.transactionattributetype import TransactionAttributeType
from boa3.internal.model.variable import Variable


class GetAttributeFeeMethod(PolicyContractMethod):

def __init__(self, tx_attribute_type: TransactionAttributeType):
from boa3.internal.model.type.type import Type
identifier = 'get_attribute_fee'
native_identifier = 'getAttributeFee'
args: dict[str, Variable] = {
'attribute_type': Variable(tx_attribute_type)
}
super().__init__(identifier, native_identifier, args, return_type=Type.int)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from boa3.internal.model.builtin.interop.nativecontract import PolicyContractMethod
from boa3.internal.model.builtin.interop.policy.transactionattributetype import TransactionAttributeType
from boa3.internal.model.variable import Variable


class SetAttributeFeeMethod(PolicyContractMethod):

def __init__(self, tx_attribute_type: TransactionAttributeType):
from boa3.internal.model.type.type import Type
identifier = 'set_attribute_fee'
native_identifier = 'setAttributeFee'
args: dict[str, Variable] = {
'attribute_type': Variable(tx_attribute_type),
'value': Variable(Type.int),
}
super().__init__(identifier, native_identifier, args, return_type=Type.none)
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from typing import Any

from boa3.internal.model.symbol import ISymbol
from boa3.internal.model.type.itype import IType
from boa3.internal.model.type.primitive.inttype import IntType
from boa3.internal.neo3.network.payloads.transactionattributetype import TransactionAttributeType as TransactionAttribute


class TransactionAttributeType(IntType):
"""
A class used to represent Neo TransactionAttributeType
"""

def __init__(self):
super().__init__()
self._identifier = 'TransactionAttributeType'

@classmethod
def build(cls, value: Any) -> IType:
if cls._is_type_of(value):
from boa3.internal.model.builtin.interop.interop import Interop
return Interop.TransactionAttributeType

@classmethod
def _is_type_of(cls, value: Any):
return isinstance(value, (TransactionAttribute, TransactionAttributeType))

@property
def symbols(self) -> dict[str, ISymbol]:
"""
Gets the class symbols of this type

:return: a dictionary that maps each symbol in the module with its name
"""
from boa3.internal.model.variable import Variable

_symbols = super().symbols
_symbols.update({name: Variable(self) for name in TransactionAttribute.__members__.keys()})

return _symbols

def get_value(self, symbol_id) -> Any:
"""
Gets the literal value of a symbol

:return: the value if this type has this symbol. None otherwise.
"""
if symbol_id in self.symbols:
return TransactionAttribute.__members__[symbol_id]

return None
4 changes: 3 additions & 1 deletion boa3/internal/model/builtin/native/policyclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ def class_methods(self) -> dict[str, Method]:
'get_fee_per_byte': Interop.GetFeePerByte,
'get_exec_fee_factor': Interop.GetExecFeeFactor,
'get_storage_price': Interop.GetStoragePrice,
'is_blocked': Interop.IsBlocked
'get_attribute_fee': Interop.GetAttributeFee,
'is_blocked': Interop.IsBlocked,
'set_attribute_fee': Interop.SetAttributeFee,
}
return super().class_methods

Expand Down
3 changes: 2 additions & 1 deletion boa3/internal/model/sc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@ def package_symbols(cls, package: str = None) -> Package | None:
Interop.VMStateType,
Interop.CallFlagsType,
Interop.OracleResponseCode,
Builtin.NeoAccountState
Builtin.NeoAccountState,
Interop.TransactionAttributeType,
],
)
# endregion
Expand Down
35 changes: 35 additions & 0 deletions boa3/internal/neo3/network/payloads/transactionattributetype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from enum import IntFlag


class TransactionAttributeType(IntFlag):
"""
Represents the TransactionAttributeType for running smart contracts.
"""

HIGH_PRIORITY = 0x01
"""
Indicates that the transaction is of high priority.

:meta hide-value:
"""

ORACLE_RESPONSE = 0x11
"""
Indicates that the transaction is an oracle response

:meta hide-value:
"""

NOT_VALID_BEFORE = 0x20
"""
Indicates that the transaction is not valid before height.

:meta hide-value:
"""

CONFLICTS = 0x21
"""
Indicates that the transaction conflicts with hash.

:meta hide-value:
"""
27 changes: 26 additions & 1 deletion boa3/sc/contracts/policycontract.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
'PolicyContract',
]

from boa3.internal.neo3.network.payloads.transactionattributetype import TransactionAttributeType
from boa3.sc.types import UInt160


Expand Down Expand Up @@ -50,7 +51,20 @@ def get_storage_price(cls) -> int:
>>> PolicyContract.get_storage_price()
100000

:return: the snapshot used to read data
:return: the storage price
:rtype: int
"""
pass

@classmethod
def get_attribute_fee(cls, attribute_type: TransactionAttributeType) -> int:
"""
Gets the fee for attribute.

>>> PolicyContract.get_attribute_fee(TransactionAttributeType.HIGH_PRIORITY)
0

:return: the fee for attribute
:rtype: int
"""
pass
Expand All @@ -70,3 +84,14 @@ def is_blocked(cls, account: UInt160) -> bool:
:rtype: bool
"""
pass

@classmethod
def set_attribute_fee(cls, attribute_type: TransactionAttributeType, value: int) -> None:
"""
Sets the fee for attribute. You need to sign the transaction using a committee member, otherwise, this function
will throw an error.

>>> PolicyContract.set_attribute_fee(TransactionAttributeType.HIGH_PRIORITY, 10)
None
"""
pass
4 changes: 3 additions & 1 deletion boa3/sc/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
'VMState',
'CallFlags',
'OracleResponseCode',
'NeoAccountState'
'NeoAccountState',
'TransactionAttributeType',
]

from typing import Any
Expand All @@ -53,6 +54,7 @@
from boa3.internal.neo3.contracts.namedcurve import NamedCurve
from boa3.internal.neo3.contracts.native import Role
from boa3.internal.neo3.network.payloads import OracleResponseCode
from boa3.internal.neo3.network.payloads.transactionattributetype import TransactionAttributeType
from boa3.internal.neo3.network.payloads.verification import WitnessScope, WitnessRuleAction, WitnessConditionType
from boa3.internal.neo3.vm import VMState

Expand Down
8 changes: 8 additions & 0 deletions boa3_test/test_sc/native_test/policy/GetAttributeFee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from boa3.sc.compiletime import public
from boa3.sc.contracts import PolicyContract
from boa3.sc.types import TransactionAttributeType


@public
def main(tx_att: TransactionAttributeType) -> int:
return PolicyContract.get_attribute_fee(tx_att)
13 changes: 13 additions & 0 deletions boa3_test/test_sc/native_test/policy/SetAttributeFee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from boa3.sc.compiletime import public
from boa3.sc.contracts import PolicyContract
from boa3.sc.types import TransactionAttributeType


@public
def main(tx_att: TransactionAttributeType, value: int):
PolicyContract.set_attribute_fee(tx_att, value)


@public
def get_tx_attr(tx_att: TransactionAttributeType) -> int:
return PolicyContract.get_attribute_fee(tx_att)
33 changes: 33 additions & 0 deletions boa3_test/tests/compiler_tests/test_native/test_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from boa3.internal import constants
from boa3.internal.exception import CompilerError, CompilerWarning
from neo3.network.payloads import verification
from boa3.internal.neo3.network.payloads.transactionattributetype import TransactionAttributeType
from boa3_test.tests import boatestcase


Expand Down Expand Up @@ -40,6 +42,37 @@ async def test_get_hash_deprecated(self):
result, _ = await self.call('main', [], return_type=types.UInt160)
self.assertEqual(expected, result)

async def test_get_attribute_fee(self):
await self.set_up_contract('GetAttributeFee.py')

result, _ = await self.call('main', [TransactionAttributeType.HIGH_PRIORITY], return_type=int)
self.assertIsInstance(result, int)

with self.assertRaises(boatestcase.FaultException) as context:
await self.call('main', [19999999], return_type=int)
self.assertRegex(str(context.exception), 'bigint does not fit into uint8')

with self.assertRaises(boatestcase.FaultException) as context:
await self.call('main', [20], return_type=int)
self.assertRegex(str(context.exception), 'invalid attribute type: 20')

async def test_set_attribute_fee(self):
await self.set_up_contract('SetAttributeFee.py')

signer = verification.Signer(
self.genesis.script_hash,
verification.WitnessScope.GLOBAL
)
result, _ = await self.call('main', [TransactionAttributeType.HIGH_PRIORITY, 100],
return_type=None, signers=[signer], signing_accounts=[self.genesis])

result, _ = await self.call('get_tx_attr', [TransactionAttributeType.HIGH_PRIORITY], return_type=int)
self.assertEqual(result, 100)

with self.assertRaises(boatestcase.FaultException) as context:
await self.call('main', [TransactionAttributeType.HIGH_PRIORITY, 100], return_type=int)
self.assertRegex(str(context.exception), 'invalid committee signature')

async def test_get_exec_fee_factor(self):
await self.set_up_contract('GetExecFeeFactor.py')

Expand Down
Loading