Skip to content

Commit

Permalink
#86dthh0zp - Update native PolicyContract
Browse files Browse the repository at this point in the history
  • Loading branch information
luc10921 committed May 16, 2024
1 parent 49731b6 commit 50bf881
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 9 deletions.
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

0 comments on commit 50bf881

Please sign in to comment.