diff --git a/rainbowadn/chain/reduction/reductionstageprotocol.py b/rainbowadn/chain/reduction/reductionstageprotocol.py index 76c4681..2457d3e 100644 --- a/rainbowadn/chain/reduction/reductionstageprotocol.py +++ b/rainbowadn/chain/reduction/reductionstageprotocol.py @@ -34,7 +34,7 @@ class ReductionStageProtocol( if previous.reference.null(): return self.protocol.initial(previous.factory) else: - return previous.reference.resolve() + return self.protocol.header_filter(previous.reference.resolve()) def derive_header( self, diff --git a/rainbowadn/data/collection/collection_interface/activecollectioninterface.py b/rainbowadn/data/collection/collection_interface/activecollectioninterface.py deleted file mode 100644 index 8a0ef17..0000000 --- a/rainbowadn/data/collection/collection_interface/activecollectioninterface.py +++ /dev/null @@ -1,14 +0,0 @@ -from typing import Generic, TypeVar - -from rainbowadn.data.collection.collection_interface.collectioninterface import CollectionInterface -from rainbowadn.hashing.hashpoint import HashPoint - -__all__ = ('ActiveCollectionInterface',) - -CollectionType = TypeVar('CollectionType') -KeyType = TypeVar('KeyType') - - -class ActiveCollectionInterface(CollectionInterface[CollectionType], Generic[CollectionType, KeyType]): - def add(self, key: HashPoint[KeyType]) -> 'ActiveCollectionInterface[KeyType]': - raise NotImplementedError diff --git a/rainbowadn/data/collection/collection_interface/collectionfactory.py b/rainbowadn/data/collection/collection_interface/collectionfactory.py deleted file mode 100644 index b8a02c6..0000000 --- a/rainbowadn/data/collection/collection_interface/collectionfactory.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import Generic, TypeVar - -from rainbowadn.hashing.nullability.nullablereference import NullableReference - -__all__ = ('CollectionFactory',) - -CollectionType = TypeVar('CollectionType') -InterfaceType = TypeVar('InterfaceType') - - -class CollectionFactory( - Generic[CollectionType, InterfaceType], -): - """вперёд, уроды, вас ждут заводы""" - - def from_reference(self, source: NullableReference[CollectionType]) -> InterfaceType: - raise NotImplementedError diff --git a/rainbowadn/data/collection/collection_interface/querycollectioninterface.py b/rainbowadn/data/collection/collection_interface/querycollectioninterface.py deleted file mode 100644 index f8e77ec..0000000 --- a/rainbowadn/data/collection/collection_interface/querycollectioninterface.py +++ /dev/null @@ -1,13 +0,0 @@ -from typing import Generic, TypeVar - -from rainbowadn.hashing.hashpoint import HashPoint -from rainbowadn.hashing.nullability.nullable import Nullable - -__all__ = ('QueryCollectionInterface',) - -KeyType = TypeVar('KeyType') - - -class QueryCollectionInterface(Generic[KeyType]): - def query(self, key: HashPoint[KeyType]) -> Nullable[HashPoint[KeyType]]: - raise NotImplementedError diff --git a/rainbowadn/data/collection/keymetadataquerycollection.py b/rainbowadn/data/collection/keymetadataquerycollection.py deleted file mode 100644 index cd8de8c..0000000 --- a/rainbowadn/data/collection/keymetadataquerycollection.py +++ /dev/null @@ -1,36 +0,0 @@ -from typing import Generic, TypeVar - -from rainbowadn.data.collection.collection_interface.querycollectioninterface import QueryCollectionInterface -from rainbowadn.data.collection.keymetadata import KeyMetadata -from rainbowadn.hashing.hashpoint import HashPoint -from rainbowadn.hashing.nullability.notnull import NotNull -from rainbowadn.hashing.nullability.null import Null -from rainbowadn.hashing.nullability.nullable import Nullable - -__all__ = ('KeyMetadataQueryCollection',) - -ActiveKeyType = TypeVar('ActiveKeyType') -MetaDataType = TypeVar('MetaDataType') - - -class KeyMetadataQueryCollection(QueryCollectionInterface[ActiveKeyType], Generic[ActiveKeyType, MetaDataType]): - def __init__( - self, - metadata: HashPoint[MetaDataType], - collection: QueryCollectionInterface[KeyMetadata[ActiveKeyType, MetaDataType]], - ): - assert isinstance(metadata, HashPoint) - assert isinstance(collection, QueryCollectionInterface) - self.metadata = metadata - self.collection = collection - - def query(self, key: HashPoint[ActiveKeyType]) -> Nullable[HashPoint[ActiveKeyType]]: - assert isinstance(key, HashPoint) - result: Nullable[ - HashPoint[KeyMetadata[ActiveKeyType, MetaDataType]] - ] = self.collection.query(HashPoint.of(KeyMetadata(key, self.metadata))) - assert isinstance(result, Nullable) - if result.null(): - return Null() - else: - return NotNull(result.resolve().resolve().key) diff --git a/rainbowadn/data/collection/mapping/__init__.py b/rainbowadn/data/collection/mapping/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/rainbowadn/data/collection/mapping/activemapping.py b/rainbowadn/data/collection/mapping/activemapping.py deleted file mode 100644 index 4b31d03..0000000 --- a/rainbowadn/data/collection/mapping/activemapping.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import Generic, TypeVar - -from rainbowadn.data.collection.collection_interface.activecollectioninterface import ActiveCollectionInterface -from rainbowadn.data.collection.keyvalue import KeyValue -from rainbowadn.hashing.hashpoint import HashPoint - -__all__ = ('ActiveMapping',) - -KVKeyType = TypeVar('KVKeyType') -KVValueType = TypeVar('KVValueType') - - -class ActiveMapping(Generic[KVKeyType, KVValueType]): - def __init__( - self, - collection: ActiveCollectionInterface[KeyValue[KVKeyType, KVValueType]] - ): - assert isinstance(collection, ActiveCollectionInterface) - self.collection = collection - - def add(self, key: HashPoint[KVKeyType], value: HashPoint[KVValueType]) -> 'ActiveMapping[KVKeyType, KVValueType]': - assert isinstance(key, HashPoint) - assert isinstance(value, HashPoint) - return ActiveMapping( - self.collection.add(HashPoint.of(KeyValue(key, value))) - ) diff --git a/rainbowadn/data/collection/mapping/querymapping.py b/rainbowadn/data/collection/mapping/querymapping.py deleted file mode 100644 index e780d12..0000000 --- a/rainbowadn/data/collection/mapping/querymapping.py +++ /dev/null @@ -1,38 +0,0 @@ -from typing import Generic, TypeVar - -from rainbowadn.data.collection.collection_interface.querycollectioninterface import QueryCollectionInterface -from rainbowadn.data.collection.keyvalue import KeyValue -from rainbowadn.hashing.hashpoint import HashPoint -from rainbowadn.hashing.nullability.notnull import NotNull -from rainbowadn.hashing.nullability.null import Null -from rainbowadn.hashing.nullability.nullable import Nullable - -__all__ = ('QueryMapping',) - -KVKeyType = TypeVar('KVKeyType') -KVValueType = TypeVar('KVValueType') - - -class QueryMapping(Generic[KVKeyType, KVValueType]): - def __init__( - self, - collection: QueryCollectionInterface[KeyValue[KVKeyType, KVValueType]], - empty_value: HashPoint[KVValueType] - ): - assert isinstance(collection, QueryCollectionInterface) - assert isinstance(empty_value, HashPoint) - self.collection = collection - self.empty_value = empty_value - - def query(self, key: HashPoint[KVKeyType]) -> Nullable[HashPoint[KVValueType]]: - assert isinstance(key, HashPoint) - query_result: Nullable[ - HashPoint[KeyValue[KVKeyType, KVValueType]] - ] = self.collection.query(HashPoint.of(KeyValue(key, self.empty_value))) - assert isinstance(query_result, Nullable) - if query_result.null(): - return Null() - else: - key_value: KeyValue[KVKeyType, KVValueType] = query_result.resolve().resolve() - assert isinstance(key_value, KeyValue) - return NotNull(key_value.value) diff --git a/rainbowadn/data/collection/pair.py b/rainbowadn/data/collection/pair.py index 3b89700..7af3dad 100644 --- a/rainbowadn/data/collection/pair.py +++ b/rainbowadn/data/collection/pair.py @@ -60,3 +60,6 @@ class PairFactory( ResolverOrigin(self.e0_factory, source[:HashPoint.HASH_LENGTH], resolver).hash_point(), ResolverOrigin(self.e1_factory, source[HashPoint.HASH_LENGTH:], resolver).hash_point(), ) + + def loose(self) -> RainbowFactory[Pair[E0Type, E1Type]]: + return self diff --git a/rainbowadn/data/collection/trees/binary/activebinarytree.py b/rainbowadn/data/collection/trees/binary/activebinarytree.py index d54df1f..5dc6721 100644 --- a/rainbowadn/data/collection/trees/binary/activebinarytree.py +++ b/rainbowadn/data/collection/trees/binary/activebinarytree.py @@ -1,16 +1,12 @@ from typing import Generic, Optional, TypeVar -from rainbowadn.data.collection.collection_interface.activecollectioninterface import ActiveCollectionInterface -from rainbowadn.data.collection.collection_interface.querycollectioninterface import QueryCollectionInterface +from rainbowadn.data.collection.collection_interface.collectioninterface import CollectionInterface from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory -from rainbowadn.data.collection.keymetadataquerycollection import KeyMetadataQueryCollection from rainbowadn.data.collection.trees.binary.balancedtreecreationprotocol import BalancedTreeCreationProtocol from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, BinaryTreeFactory from rainbowadn.data.collection.trees.binary.binarytreebalancingprotocol import BinaryTreeBalancingProtocol from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol -from rainbowadn.data.collection.trees.binary.querybinarytree import QueryBinaryTree from rainbowadn.data.collection.trees.comparison.comparator import (Comparator, Comparison, Equal, Left, Replace, Right) -from rainbowadn.data.collection.trees.comparison.keyedcomparator import KeyedComparator from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.nullability.null import Null from rainbowadn.hashing.nullability.nullablereference import NullableReference @@ -23,7 +19,7 @@ MetaDataType = TypeVar('MetaDataType') class ActiveBinaryTree( - ActiveCollectionInterface[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]], ActiveKeyType], + CollectionInterface[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]], Generic[ActiveKeyType, MetaDataType] ): def __init__( @@ -85,14 +81,14 @@ class ActiveBinaryTree( def pop( self, - tree_split: tuple[ + split: tuple[ 'ActiveBinaryTree[ActiveKeyType, MetaDataType]', HashPoint[ActiveKeyType], HashPoint[MetaDataType], 'ActiveBinaryTree[ActiveKeyType, MetaDataType]' ] ) -> tuple['ActiveBinaryTree[ActiveKeyType, MetaDataType]', HashPoint[ActiveKeyType]]: - treel, original, _, treer = tree_split + treel, original, _, treer = split if (splitl := self.creation.split(treel)) is None: return treer, original else: @@ -106,11 +102,11 @@ class ActiveBinaryTree( if (split := self.creation.split(self)) is None: return self else: - treel, original, _, treer = tree_split = split + treel, original, _, treer = split comparison: Comparison = self.comparator.compare(original, key) assert isinstance(comparison, Comparison) if isinstance(comparison, Equal): - return self.pop(tree_split)[0] + return self.pop(split)[0] elif isinstance(comparison, Left): return self.creation.tree(treel.remove(key), treer, original) elif isinstance(comparison, Right): @@ -118,11 +114,27 @@ class ActiveBinaryTree( else: raise TypeError - def query_tree(self) -> QueryCollectionInterface[ActiveKeyType]: - return KeyMetadataQueryCollection( - self.protocol.empty_metadata(), - QueryBinaryTree(KeyedComparator(self.comparator), self.reference) - ) + def contains(self, key: HashPoint[ActiveKeyType]) -> bool: + assert isinstance(key, HashPoint) + if (split := self.creation.split(self)) is None: + return False + else: + treel, original, _, treer = split + comparison: Comparison = self.comparator.compare(original, key) + assert isinstance(comparison, Comparison) + if isinstance(comparison, Equal): + return True + elif isinstance(comparison, Left): + return treel.contains(key) + elif isinstance(comparison, Right): + return treer.contains(key) + else: + raise TypeError + + def loose(self) -> CollectionInterface[ + BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] + ]: + return self class ActiveCreationProtocol(BalancedTreeCreationProtocol[ActiveKeyType, MetaDataType, ActiveBinaryTree]): diff --git a/rainbowadn/data/collection/trees/binary/querybinarytree.py b/rainbowadn/data/collection/trees/binary/querybinarytree.py deleted file mode 100644 index ccce22a..0000000 --- a/rainbowadn/data/collection/trees/binary/querybinarytree.py +++ /dev/null @@ -1,46 +0,0 @@ -from typing import Generic, TypeVar - -from rainbowadn.data.collection.collection_interface.querycollectioninterface import QueryCollectionInterface -from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree -from rainbowadn.data.collection.trees.comparison.comparator import Comparator, Comparison, Equal, Left, Right -from rainbowadn.hashing.hashpoint import HashPoint -from rainbowadn.hashing.nullability.notnull import NotNull -from rainbowadn.hashing.nullability.null import Null -from rainbowadn.hashing.nullability.nullable import Nullable -from rainbowadn.hashing.nullability.nullablereference import NullableReference - -__all__ = ('QueryBinaryTree',) - -KeyType = TypeVar('KeyType') - - -class QueryBinaryTree(QueryCollectionInterface[KeyType], Generic[KeyType]): - def __init__( - self, comparator: Comparator[KeyType], reference: NullableReference[BinaryTree[KeyType]] - ): - assert isinstance(comparator, Comparator) - assert isinstance(reference, NullableReference) - self.comparator = comparator - self.reference = reference - - def query(self, key: HashPoint[KeyType]) -> Nullable[HashPoint[KeyType]]: - assert isinstance(key, HashPoint) - reference: Nullable[HashPoint[BinaryTree[KeyType]]] = self.reference.reference - assert isinstance(reference, Nullable) - if reference.null(): - return Null() - else: - hash_point: HashPoint[BinaryTree[KeyType]] = reference.resolve() - assert isinstance(hash_point, HashPoint) - tree: BinaryTree[KeyType] = hash_point.resolve() - assert isinstance(tree, BinaryTree) - comparison: Comparison = self.comparator.compare(tree.key, key) - assert isinstance(comparison, Comparison) - if isinstance(comparison, Equal): - return NotNull(tree.key) - elif isinstance(comparison, Left): - return QueryBinaryTree(self.comparator, tree.treel).query(key) - elif isinstance(comparison, Right): - return QueryBinaryTree(self.comparator, tree.treer).query(key) - else: - raise TypeError diff --git a/rainbowadn/encryption/encrypted.py b/rainbowadn/encryption/encrypted.py index 274a01d..da0142c 100644 --- a/rainbowadn/encryption/encrypted.py +++ b/rainbowadn/encryption/encrypted.py @@ -17,6 +17,8 @@ EncryptedType = TypeVar('EncryptedType') class Encrypted(RecursiveMentionable, Generic[EncryptedType]): + """unstable""" + def __init__( self, key: bytes, @@ -148,9 +150,6 @@ class EncryptedFactory(RainbowFactory[Encrypted[EncryptedType]], Generic[Encrypt decrypted ) - def loose(self) -> RainbowFactory[Encrypted[EncryptedType]]: - return self - class EncryptedResolver(HashResolver): def __init__(self, mapping: dict[bytes, HashPoint[Encrypted]], key: bytes): diff --git a/rainbowadn/testing/test_all.py b/rainbowadn/testing/test_all.py index 7cd54be..c6afd52 100644 --- a/rainbowadn/testing/test_all.py +++ b/rainbowadn/testing/test_all.py @@ -11,6 +11,7 @@ from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface from rainbowadn.chain.reduction.reductionchainmetafactory import ReductionChainMetaFactory from rainbowadn.data.atomic.integer import Integer from rainbowadn.data.atomic.plain import Plain +from rainbowadn.data.collection.pair import Pair, PairFactory from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinaryTree from rainbowadn.data.collection.trees.binary.avl import AVLBTBP from rainbowadn.data.collection.trees.comparison.comparator import Replace @@ -18,6 +19,7 @@ from rainbowadn.data.collection.trees.comparison.plaincomparator import PlainCom from rainbowadn.encryption.encrypted import Encrypted from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.nullability.notnull import NotNull +from rainbowadn.hashing.rainbow_factory import RainbowFactory from rainbowadn.hashing.resolvermetaorigin import ResolverMetaOrigin from rainbowadn.testing.dictresolver import DictResolver from rainbowadn.v13.algo import MINT_CONST @@ -31,6 +33,7 @@ from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot class TestAll(unittest.TestCase): """examples rather than real tests""" + def test_bankchain(self): with self.subTest('setup'): dr = DictResolver() @@ -84,13 +87,14 @@ class TestAll(unittest.TestCase): return delta dr = DictResolver() - n = 10000 + n = 2500 + keysize = 7 with self.subTest('create empty'): - btree = WrisbtRoot.empty(WrisbtParametres(1, 5)) + btree = WrisbtRoot.empty(WrisbtParametres(1, keysize)) measure('init') with self.subTest('add keys', n=n): for _ in range(n): - key = os.urandom(5) + key = os.urandom(keysize) assert not btree.contains(key) btree = btree.add(key) assert btree.contains(key) @@ -105,7 +109,7 @@ class TestAll(unittest.TestCase): measure('resolve and iterate') with self.subTest('resolve and add', n=n): for _ in range(n): - key = os.urandom(5) + key = os.urandom(keysize) assert not btree.contains(key) btree = btree.add(key) assert btree.contains(key) @@ -114,12 +118,20 @@ class TestAll(unittest.TestCase): def test_wrisbt_index(self): with self.subTest('create empty'): - chain: ChainCollectionInterface[Any, Plain, WrisbtRoot] = BlockChainFactory( - WrisbtChainProtocol(Plain.factory(), 2).loose() + factory: RainbowFactory[Pair[Plain, Plain]] = PairFactory(Plain.factory(), Plain.factory()).loose() + chain: ChainCollectionInterface[Any, Pair[Plain, Plain], WrisbtRoot] = BlockChainFactory( + WrisbtChainProtocol(factory, 2).loose() ).empty().loose() with self.subTest('fill'): for _ in range(1000): - chain = chain.add(HashPoint.of(Plain(os.urandom(16)))) + chain = chain.add( + HashPoint.of( + Pair( + HashPoint.of(Plain(os.urandom(16))), + HashPoint.of(Plain(os.urandom(16))) + ) + ) + ) with self.subTest('check'): assert chain with self.subTest('measure height'): @@ -135,6 +147,14 @@ class TestAll(unittest.TestCase): tree = tree.add(HashPoint.of(Plain(bytes([ord('A') + i])))) print(tree.reference.str(0)) + def test_avl_stress(self): + tree: ActiveBinaryTree[Plain, Integer] = ActiveBinaryTree.empty( + AVLBTBP(PlainComparator(Replace())), Plain.factory() + ) + for i in range(250): + tree = tree.add(HashPoint.of(Plain(os.urandom(16)))) + print(tree.loose().reference.reference.resolve().resolve().key.resolve().metadata.resolve().integer) + def test_encryption(self): with self.subTest('setup'): key = b'a' * 32 diff --git a/rainbowadn/v13/bankstate.py b/rainbowadn/v13/bankstate.py index a3fa8b5..880fd90 100644 --- a/rainbowadn/v13/bankstate.py +++ b/rainbowadn/v13/bankstate.py @@ -101,8 +101,8 @@ class BankState(RecursiveMentionable, StaticMentionable): minted: ActiveBinaryTree[Coin, Integer] = self.minted_tree() used: ActiveBinaryTree[Coin, Integer] = self.used_tree() for in_coin in coins: - assert not minted.query_tree().query(in_coin).null() - assert used.query_tree().query(in_coin).null() + assert minted.contains(in_coin) + assert not used.contains(in_coin) used = used.add(in_coin) return BankState(self.minted, used.reference, self.miner, self.length) @@ -114,7 +114,7 @@ class BankState(RecursiveMentionable, StaticMentionable): miner = self.miner_nullable() minted: ActiveBinaryTree[Coin, Integer] = self.minted_tree() for coin, miner in transaction.iter_coins(self.mint(), miner): - assert minted.query_tree().query(HashPoint.of(coin)).null() + assert not minted.contains(HashPoint.of(coin)) minted = minted.add(HashPoint.of(coin)) assert isinstance(minted, ActiveBinaryTree) return BankState(minted.reference, self.used, NullableReference(miner, self.miner.factory), self.length) diff --git a/rainbowadn/v13/transaction.py b/rainbowadn/v13/transaction.py index 5c87c11..17924be 100644 --- a/rainbowadn/v13/transaction.py +++ b/rainbowadn/v13/transaction.py @@ -90,9 +90,6 @@ class Coin(RecursiveMentionable, StaticMentionable): ResolverOrigin(Integer.factory(), source[2 * HashPoint.HASH_LENGTH:], resolver).hash_point(), ) - def __str__(self): - return f'(coin)' - def str(self, tab: int) -> str: assert isinstance(tab, int) return f'(' \ @@ -266,9 +263,6 @@ class Transaction(RecursiveMentionable, StaticMentionable): assert data.verify(self.signatures, mint) return True - def __str__(self): - return f'(transaction)' - def str(self, tab: int) -> str: assert isinstance(tab, int) return f'(' \ diff --git a/rainbowadn/wrisbt/wrisbtroot.py b/rainbowadn/wrisbt/wrisbtroot.py index 16c79d3..1f0ebf3 100644 --- a/rainbowadn/wrisbt/wrisbtroot.py +++ b/rainbowadn/wrisbt/wrisbtroot.py @@ -1,4 +1,4 @@ -from typing import Iterable, Optional +from typing import Iterable from rainbowadn.data.atomic.integer import Integer from rainbowadn.hashing.hash_point_format import hash_point_format, tabulate @@ -85,11 +85,9 @@ class WrisbtRoot(RecursiveMentionable): return list(self.root.resolve().iter_keys()) def index( - self, target: HashPoint, exclude: Optional['WrisbtRoot'] + self, target: HashPoint, exclude: 'WrisbtRoot' ) -> 'WrisbtRoot': assert isinstance(target, HashPoint) - if exclude is None: - exclude = self.empty(self.parametres) assert isinstance(exclude, WrisbtRoot) key: bytes = target.point assert isinstance(key, bytes)