From cf727d87b033338e23bd217091216335dd21d1f8 Mon Sep 17 00:00:00 2001 From: timotheyca Date: Sun, 19 Jun 2022 22:53:02 +0300 Subject: [PATCH] async --- rainbowadn/chain/block.py | 8 +- rainbowadn/chain/blockchain.py | 47 ++++---- rainbowadn/chain/blockchainprotocol.py | 2 +- rainbowadn/chain/blockcollectioninterface.py | 16 +-- rainbowadn/chain/chaincollectioninterface.py | 7 +- rainbowadn/chain/reduction/reduction.py | 4 +- .../reduction/reductionchainmetafactory.py | 10 ++ .../chain/reduction/reductionchainprotocol.py | 2 +- .../chain/reduction/reductionprotocol.py | 4 +- .../chain/reduction/reductionstageprotocol.py | 12 +- .../stages/derivation/activestageprotocol.py | 41 +++---- .../derivation/activestagestateprotocol.py | 4 +- rainbowadn/chain/stages/stage.py | 69 +++++++----- rainbowadn/chain/stages/stageprotocol.py | 6 +- rainbowadn/chain/stages/stagestateprotocol.py | 6 +- .../chain/states/activestateprotocol.py | 7 +- .../states/metareductionstateprotocol.py | 11 +- rainbowadn/chain/states/stateprotocol.py | 2 +- rainbowadn/core/asserts.py | 24 ++++ rainbowadn/core/extendableresolver.py | 20 ++++ rainbowadn/core/hash_point_format.py | 7 +- rainbowadn/core/hashpoint.py | 11 +- rainbowadn/core/hashresolver.py | 2 +- rainbowadn/core/localmetaorigin.py | 3 +- rainbowadn/core/localorigin.py | 2 +- rainbowadn/core/metaorigin.py | 3 +- .../core/nullability/nullablereference.py | 8 +- rainbowadn/core/origin.py | 2 +- rainbowadn/core/recursivementionable.py | 2 +- rainbowadn/core/resolvermetaorigin.py | 10 +- rainbowadn/core/resolverorigin.py | 9 +- rainbowadn/data/collection/array/array.py | 4 +- rainbowadn/data/collection/keymetadata.py | 6 +- rainbowadn/data/collection/pair.py | 6 +- rainbowadn/data/collection/stack/stack.py | 17 +-- .../trees/binary/actions/binarytreeaction.py | 18 +-- .../trees/binary/actions/compareaction.py | 16 +-- .../trees/binary/actions/stdactions.py | 66 ++++++----- .../trees/binary/actions/symmetric.py | 10 +- .../trees/binary/activebinarytree.py | 22 ++-- .../data/collection/trees/binary/avl.py | 51 +++++---- .../binary/balancedtreecreationprotocol.py | 12 +- .../collection/trees/binary/binarytree.py | 8 +- .../binary/binarytreebalancingprotocol.py | 4 +- .../binary/binarytreecreationprotocol.py | 8 +- .../collection/trees/comparison/comparator.py | 2 +- .../trees/comparison/hashcomparator.py | 2 +- .../trees/comparison/keyedcomparator.py | 8 +- .../trees/comparison/plaincomparator.py | 6 +- rainbowadn/encryption/encrypted.py | 39 ++++--- rainbowadn/testing/dictresolver.py | 15 ++- rainbowadn/testing/failresolver.py | 2 +- rainbowadn/testing/instrumentation.py | 6 +- rainbowadn/testing/test_all.py | 90 +++++++-------- rainbowadn/toplevel/thresholdprotocol.py | 2 +- rainbowadn/toplevel/validreference.py | 6 +- rainbowadn/v13/bankchain.py | 15 +-- rainbowadn/v13/bankprotocol.py | 14 +-- rainbowadn/v13/bankstate.py | 53 ++++----- rainbowadn/v13/signature.py | 3 +- rainbowadn/v13/transaction.py | 105 ++++++++++-------- .../wrisbt/weakreferenceindexsetbtree.py | 36 +++--- rainbowadn/wrisbt/wrisbtchainprotocol.py | 2 +- rainbowadn/wrisbt/wrisbtindex.py | 6 +- rainbowadn/wrisbt/wrisbtprotocol.py | 10 +- rainbowadn/wrisbt/wrisbtroot.py | 39 +++---- 66 files changed, 595 insertions(+), 475 deletions(-) create mode 100644 rainbowadn/core/asserts.py create mode 100644 rainbowadn/core/extendableresolver.py diff --git a/rainbowadn/chain/block.py b/rainbowadn/chain/block.py index 5fa67d3..aee7754 100644 --- a/rainbowadn/chain/block.py +++ b/rainbowadn/chain/block.py @@ -40,15 +40,15 @@ class Block(RecursiveMentionable, Generic[HeaderType, StateType]): self.state.factory, ) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) - return f'{self.previous.str(tab)}' \ + return f'{await self.previous.str(tab)}' \ f'{tabulate(tab)}(' \ f'{tabulate(tab + 1)}block' \ f'{tabulate(tab + 1)}(header)' \ - f'{tabulate(tab + 1)}{hash_point_format(self.header, tab + 1)}' \ + f'{tabulate(tab + 1)}{await hash_point_format(self.header, tab + 1)}' \ f'{tabulate(tab + 1)}(state)' \ - f'{tabulate(tab + 1)}{hash_point_format(self.state, tab + 1)}' \ + f'{tabulate(tab + 1)}{await hash_point_format(self.state, tab + 1)}' \ f'{tabulate(tab)})' diff --git a/rainbowadn/chain/blockchain.py b/rainbowadn/chain/blockchain.py index 7155b98..a0ed3c7 100644 --- a/rainbowadn/chain/blockchain.py +++ b/rainbowadn/chain/blockchain.py @@ -1,9 +1,11 @@ +import asyncio from typing import Generic, TypeVar from rainbowadn.chain.block import Block, BlockFactory from rainbowadn.chain.blockchainprotocol import BlockChainProtocol from rainbowadn.chain.chaincollectionfactory import ChainCollectionFactory from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface +from rainbowadn.core.asserts import assert_eq, assert_true from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.nullability.null import Null from rainbowadn.core.nullability.nullablereference import NullableReference @@ -52,7 +54,7 @@ class BlockChain( ]: return BlockChainFactory(self.protocol) - def add( + async def add( self, header: HashPoint[HeaderType] ) -> ChainCollectionInterface[ @@ -66,11 +68,11 @@ class BlockChain( assert isinstance(header, HashPoint) return self.factory().from_reference( NullableReference.off( - self._add(header) + await self._add(header) ) ) - def state( + async def state( self ) -> NullableReference[ StateType @@ -81,11 +83,11 @@ class BlockChain( self.protocol.state_factory ) else: - block: Block[HeaderType, StateType] = self.reference.resolve() + block: Block[HeaderType, StateType] = await self.reference.resolve() assert isinstance(block, Block) return NullableReference.of(block.state) - def _add( + async def _add( self, header: HashPoint[HeaderType] ) -> Block[ @@ -96,13 +98,13 @@ class BlockChain( return Block( self.reference, header, - self.protocol.state_protocol.derive( - self.state(), + await self.protocol.state_protocol.derive( + await self.state(), header, ) ) - def previous( + async def previous( self ) -> ChainCollectionInterface[ Block[ @@ -116,19 +118,22 @@ class BlockChain( block: Block[ HeaderType, StateType - ] = self.reference.resolve() + ] = await self.reference.resolve() assert isinstance(block, Block) return self.factory().from_reference(block.previous) - def verify(self) -> bool: + async def verify(self) -> bool: if self.reference.null(): return True else: - assert self.verify_link(self.previous().reference) - assert self.previous().verify() + previous: ChainCollectionInterface[ + Block[HeaderType, StateType], HeaderType, ActualStateType + ] = await self.previous() + assert_true(await self.verify_link(previous.reference)) + assert_true(await asyncio.create_task(previous.verify())) return True - def _verify_link( + async def _verify_link( self, block: Block[ HeaderType, @@ -143,20 +148,22 @@ class BlockChain( ) -> bool: assert isinstance(block, Block) assert isinstance(previous, NullableReference) - assert block.previous == previous + assert_eq(block.previous, previous) previous_chain = self.factory().from_reference(previous) assert isinstance(previous_chain, BlockChain) - assert self.protocol.state_protocol.verify( - previous_chain.state(), - block.header, - block.state, + assert_true( + await self.protocol.state_protocol.verify( + await previous_chain.state(), + block.header, + block.state, + ) ) return True def _actual_state_factory(self) -> RainbowFactory[ActualStateType]: return self.protocol.actual_state_factory() - def _actual_state( + async def _actual_state( self, block: Block[ HeaderType, @@ -164,7 +171,7 @@ class BlockChain( ] ) -> HashPoint[ActualStateType]: assert isinstance(block, Block) - return self.protocol.actual_state(block.state.resolve()) + return await self.protocol.actual_state(await block.state.resolve()) def loose(self) -> ChainCollectionInterface[ Block[ diff --git a/rainbowadn/chain/blockchainprotocol.py b/rainbowadn/chain/blockchainprotocol.py index 77e93c5..2216f07 100644 --- a/rainbowadn/chain/blockchainprotocol.py +++ b/rainbowadn/chain/blockchainprotocol.py @@ -30,7 +30,7 @@ class BlockChainProtocol( def actual_state_factory(self) -> RainbowFactory[ActualStateType]: raise NotImplementedError - def actual_state( + async def actual_state( self, state: StateType ) -> HashPoint[ActualStateType]: diff --git a/rainbowadn/chain/blockcollectioninterface.py b/rainbowadn/chain/blockcollectioninterface.py index 47cace3..8b3d836 100644 --- a/rainbowadn/chain/blockcollectioninterface.py +++ b/rainbowadn/chain/blockcollectioninterface.py @@ -26,14 +26,14 @@ class BlockCollectionInterface( assert isinstance(reference, NullableReference) super().__init__(reference) - def _verify_link( + async def _verify_link( self, block: BlockType, previous: NullableReference[BlockType] ) -> bool: raise NotImplementedError - def verify_link( + async def verify_link( self, previous: NullableReference[BlockType] ) -> bool: @@ -41,24 +41,24 @@ class BlockCollectionInterface( if self.reference.null(): return True else: - return self._verify_link( - self.reference.resolve(), + return await self._verify_link( + await self.reference.resolve(), previous ) def _actual_state_factory(self) -> RainbowFactory[ActualStateType]: raise NotImplementedError - def _actual_state(self, block: BlockType) -> HashPoint[ActualStateType]: + async def _actual_state(self, block: BlockType) -> HashPoint[ActualStateType]: raise NotImplementedError - def actual_state(self) -> NullableReference[ActualStateType]: + async def actual_state(self) -> NullableReference[ActualStateType]: if self.reference.null(): return NullableReference(Null(), self._actual_state_factory()) else: - return NullableReference.of(self._actual_state(self.reference.resolve())) + return NullableReference.of(await self._actual_state(await self.reference.resolve())) - def add( + async def add( self, header: HashPoint[HeaderType] ) -> 'BlockCollectionInterface[BlockType, HeaderType, ActualStateType]': diff --git a/rainbowadn/chain/chaincollectioninterface.py b/rainbowadn/chain/chaincollectioninterface.py index 0cde9a8..b5d8d3a 100644 --- a/rainbowadn/chain/chaincollectioninterface.py +++ b/rainbowadn/chain/chaincollectioninterface.py @@ -20,8 +20,11 @@ class ChainCollectionInterface( Generic[BlockType, HeaderType, ActualStateType], abc.ABC ): - def add(self, header: HashPoint[HeaderType]) -> 'ChainCollectionInterface[BlockType, HeaderType, ActualStateType]': + async def add( + self, + header: HashPoint[HeaderType] + ) -> 'ChainCollectionInterface[BlockType, HeaderType, ActualStateType]': raise NotImplementedError - def verify(self) -> bool: + async def verify(self) -> bool: raise NotImplementedError diff --git a/rainbowadn/chain/reduction/reduction.py b/rainbowadn/chain/reduction/reduction.py index 6258018..81ace99 100644 --- a/rainbowadn/chain/reduction/reduction.py +++ b/rainbowadn/chain/reduction/reduction.py @@ -34,10 +34,10 @@ class Reduction( def __factory__(self) -> RainbowFactory['Reduction[ReductorType, AccumulatorType]']: return ReductionFactory(self.reductor.factory, self.accumulator.factory) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) return f'(reduction)' \ - f'{tabulate(tab)}{hash_point_format(self.accumulator, tab)}' + f'{tabulate(tab)}{await hash_point_format(self.accumulator, tab)}' class ReductionFactory( diff --git a/rainbowadn/chain/reduction/reductionchainmetafactory.py b/rainbowadn/chain/reduction/reductionchainmetafactory.py index 1f39a3f..2ee1360 100644 --- a/rainbowadn/chain/reduction/reductionchainmetafactory.py +++ b/rainbowadn/chain/reduction/reductionchainmetafactory.py @@ -50,3 +50,13 @@ class ReductionChainMetaFactory( accumulator_factory, ) ) + + def loose(self) -> AbstractReductionChainMetaFactory[ + Block[ + ReductorType, + StateStage[ReductorType, AccumulatorType, Reduction[ReductorType, AccumulatorType]] + ], + ReductorType, + AccumulatorType + ]: + return self diff --git a/rainbowadn/chain/reduction/reductionchainprotocol.py b/rainbowadn/chain/reduction/reductionchainprotocol.py index 9dde6f9..250d8c2 100644 --- a/rainbowadn/chain/reduction/reductionchainprotocol.py +++ b/rainbowadn/chain/reduction/reductionchainprotocol.py @@ -66,7 +66,7 @@ class ReductionChainProtocol( def actual_state_factory(self) -> RainbowFactory[AccumulatorType]: return self.accumulator_factory - def actual_state( + async def actual_state( self, state: StateStage[ ReductorType, diff --git a/rainbowadn/chain/reduction/reductionprotocol.py b/rainbowadn/chain/reduction/reductionprotocol.py index a34a398..997916d 100644 --- a/rainbowadn/chain/reduction/reductionprotocol.py +++ b/rainbowadn/chain/reduction/reductionprotocol.py @@ -12,7 +12,7 @@ AccumulatorType = TypeVar('AccumulatorType') class ReductionProtocol(Generic[ReductorType, AccumulatorType]): - def reduce( + async def reduce( self, reduction: Reduction[ReductorType, AccumulatorType] ) -> ReductionResult[ReductorType, AccumulatorType]: @@ -21,7 +21,7 @@ class ReductionProtocol(Generic[ReductorType, AccumulatorType]): def initial(self, factory: RainbowFactory[AccumulatorType]) -> HashPoint[AccumulatorType]: raise NotImplementedError - def header_filter( + async def header_filter( self, state: HashPoint[AccumulatorType] ) -> HashPoint[AccumulatorType]: diff --git a/rainbowadn/chain/reduction/reductionstageprotocol.py b/rainbowadn/chain/reduction/reductionstageprotocol.py index d8863dc..e3fe5f9 100644 --- a/rainbowadn/chain/reduction/reductionstageprotocol.py +++ b/rainbowadn/chain/reduction/reductionstageprotocol.py @@ -26,7 +26,7 @@ class ReductionStageProtocol( self.protocol = protocol super().__init__() - def _derive_accumulator( + async def _derive_accumulator( self, previous: NullableReference[AccumulatorType], ) -> HashPoint[AccumulatorType]: @@ -34,9 +34,9 @@ class ReductionStageProtocol( if previous.null(): return self.protocol.initial(previous.factory) else: - return self.protocol.header_filter(previous.hashpoint()) + return await self.protocol.header_filter(previous.hashpoint()) - def derive_header( + async def derive_header( self, previous: NullableReference[AccumulatorType], header: HashPoint[ReductorType] @@ -46,7 +46,7 @@ class ReductionStageProtocol( return HashPoint.of( Reduction( header, - self._derive_accumulator(previous) + await self._derive_accumulator(previous) ) ) @@ -63,9 +63,9 @@ class ReductionStageProtocol( else: raise TypeError - def derive_stage_or_state( + async def derive_stage_or_state( self, stage: HashPoint[Reduction[ReductorType, AccumulatorType]] ) -> Derived[ReductorType, Reduction[ReductorType, AccumulatorType]]: assert isinstance(stage, HashPoint) - return self._derived_from_reduced(self.protocol.reduce(stage.resolve())) + return self._derived_from_reduced(await self.protocol.reduce(await stage.resolve())) diff --git a/rainbowadn/chain/stages/derivation/activestageprotocol.py b/rainbowadn/chain/stages/derivation/activestageprotocol.py index 802d837..75cb2ca 100644 --- a/rainbowadn/chain/stages/derivation/activestageprotocol.py +++ b/rainbowadn/chain/stages/derivation/activestageprotocol.py @@ -5,6 +5,7 @@ from rainbowadn.chain.stages.derivation.derivedstage import DerivedStage from rainbowadn.chain.stages.derivation.derivedstate import DerivedState from rainbowadn.chain.stages.stage import StageStage, StageStageFactory, StateStage from rainbowadn.chain.stages.stageprotocol import StageProtocol +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.nullability.null import Null from rainbowadn.core.nullability.nullablereference import NullableReference @@ -21,21 +22,21 @@ class ActiveStageProtocol( StageProtocol[HeaderType, BaseStateType, StageType], Generic[HeaderType, BaseStateType, StageType] ): - def derive_header( + async def derive_header( self, previous: NullableReference[BaseStateType], header: HashPoint[HeaderType], ) -> HashPoint[StageType]: raise NotImplementedError - def derive_stage_or_state( + async def derive_stage_or_state( self, stage: HashPoint[StageType], ) -> Derived[BaseStateType, StageType]: raise NotImplementedError @classmethod - def _previous_base_state( + async def _previous_base_state( cls, previous_reference: NullableReference[StateStage[HeaderType, BaseStateType, StageType]], base_state_factory: RainbowFactory[BaseStateType], @@ -45,11 +46,11 @@ class ActiveStageProtocol( if previous_reference.null(): return NullableReference(Null(), base_state_factory) else: - previous_state_stage: StateStage[HeaderType, BaseStateType, StageType] = previous_reference.resolve() + previous_state_stage: StateStage[HeaderType, BaseStateType, StageType] = await previous_reference.resolve() assert isinstance(previous_state_stage, StateStage) return NullableReference.of(previous_state_stage.state) - def _derive_cycle( + async def _derive_cycle( self, stage: StageStage[HeaderType, BaseStateType, StageType], stage_factory: RainbowFactory[StageType] @@ -57,7 +58,7 @@ class ActiveStageProtocol( assert isinstance(stage, StageStage) assert isinstance(stage_factory, RainbowFactory) while True: - derived = self.derive_stage_or_state(stage.stage) + derived: Derived[BaseStateType, StageType] = await self.derive_stage_or_state(stage.stage) assert isinstance(derived, Derived) if isinstance(derived, DerivedStage): stage = StageStage(self, NullableReference.off(stage), derived.stage) @@ -67,7 +68,7 @@ class ActiveStageProtocol( else: raise TypeError - def _derive_initial_stage( + async def _derive_initial_stage( self, previous: NullableReference[BaseStateType], header: HashPoint[HeaderType], @@ -85,10 +86,10 @@ class ActiveStageProtocol( stage_factory ) ), - self.derive_header(previous, header) + await self.derive_header(previous, header) ) - def derive_full( + async def derive_full( self, previous_reference: NullableReference[StateStage[HeaderType, BaseStateType, StageType]], header: HashPoint[HeaderType], @@ -99,9 +100,9 @@ class ActiveStageProtocol( assert isinstance(header, HashPoint) assert isinstance(base_state_factory, RainbowFactory) assert isinstance(stage_factory, RainbowFactory) - return self._derive_cycle( - self._derive_initial_stage( - self._previous_base_state( + return await self._derive_cycle( + await self._derive_initial_stage( + await self._previous_base_state( previous_reference, base_state_factory ), @@ -111,7 +112,7 @@ class ActiveStageProtocol( stage_factory ) - def verify_header( + async def verify_header( self, previous: NullableReference[BaseStateType], header: HashPoint[HeaderType], @@ -120,35 +121,35 @@ class ActiveStageProtocol( assert isinstance(previous, NullableReference) assert isinstance(header, HashPoint) assert isinstance(stage, HashPoint) - assert stage == self.derive_header(previous, header) + assert_eq(stage, await self.derive_header(previous, header)) return True - def verify_stage( + async def verify_stage( self, previous: HashPoint[StageType], stage: HashPoint[StageType] ) -> bool: assert isinstance(previous, HashPoint) assert isinstance(stage, HashPoint) - derived = self.derive_stage_or_state(previous) + derived: Derived[BaseStateType, StageType] = await self.derive_stage_or_state(previous) assert isinstance(derived, Derived) if isinstance(derived, DerivedStage): - assert stage == derived.stage + assert_eq(stage, derived.stage) return True else: raise TypeError - def verify_state( + async def verify_state( self, stage: HashPoint[StageType], state: HashPoint[BaseStateType] ) -> bool: assert isinstance(stage, HashPoint) assert isinstance(state, HashPoint) - derived = self.derive_stage_or_state(stage) + derived: Derived[BaseStateType, StageType] = await self.derive_stage_or_state(stage) assert isinstance(derived, Derived) if isinstance(derived, DerivedState): - assert state == derived.state + assert_eq(state, derived.state) return True else: raise TypeError diff --git a/rainbowadn/chain/stages/derivation/activestagestateprotocol.py b/rainbowadn/chain/stages/derivation/activestagestateprotocol.py index 7d5a71d..5fa7d8a 100644 --- a/rainbowadn/chain/stages/derivation/activestagestateprotocol.py +++ b/rainbowadn/chain/stages/derivation/activestagestateprotocol.py @@ -37,7 +37,7 @@ class ActiveStageStateProtocol( self.stage_factory = stage_factory self.base_state_factory = base_state_factory - def derive( + async def derive( self, previous: NullableReference[ StateStage[ @@ -56,7 +56,7 @@ class ActiveStageStateProtocol( ]: assert isinstance(previous, NullableReference) assert isinstance(header, HashPoint) - return self.protocol.derive_full( + return await self.protocol.derive_full( previous, header, self.base_state_factory, diff --git a/rainbowadn/chain/stages/stage.py b/rainbowadn/chain/stages/stage.py index af5fc4e..6c80b67 100644 --- a/rainbowadn/chain/stages/stage.py +++ b/rainbowadn/chain/stages/stage.py @@ -1,6 +1,7 @@ from typing import Generic, Iterable, TypeVar from rainbowadn.chain.stages.stageprotocol import StageProtocol +from rainbowadn.core.asserts import assert_true from rainbowadn.core.hash_point_format import hash_point_format, tabulate from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashresolver import HashResolver @@ -47,7 +48,7 @@ class StageStage( self.stage = stage @classmethod - def _previous_state( + async def _previous_state( cls, previous: NullableReference['StateStage[HeaderType, BaseStateType, StageType]'], base_factory: RainbowFactory[BaseStateType], @@ -57,11 +58,11 @@ class StageStage( if previous.null(): return NullableReference(Null(), base_factory) else: - state_stage: StateStage[HeaderType, BaseStateType, StageType] = previous.resolve() + state_stage: StateStage[HeaderType, BaseStateType, StageType] = await previous.resolve() assert isinstance(state_stage, StateStage) return NullableReference.of(state_stage.state) - def verify( + async def verify( self, previous: NullableReference['StateStage[HeaderType, BaseStateType, StageType]'], header: HashPoint[HeaderType], @@ -71,22 +72,28 @@ class StageStage( assert isinstance(header, HashPoint) assert isinstance(base_factory, RainbowFactory) if self.previous.null(): - return self.protocol.verify_header( - self._previous_state(previous, base_factory), + return await self.protocol.verify_header( + await self._previous_state(previous, base_factory), header, self.stage ) else: - previous_stage: StageStage[HeaderType, BaseStateType, StageType] = self.previous.resolve() + previous_stage: StageStage[HeaderType, BaseStateType, StageType] = await self.previous.resolve() assert isinstance(previous_stage, StageStage) - return self.protocol.verify_stage( - previous_stage.stage, - self.stage - ) and previous_stage.verify( - previous, - header, - base_factory + assert_true( + await self.protocol.verify_stage( + previous_stage.stage, + self.stage + ) ) + assert_true( + await previous_stage.verify( + previous, + header, + base_factory + ) + ) + return True def points(self) -> Iterable[HashPoint]: return [*self.previous.points(), self.stage] @@ -100,10 +107,10 @@ class StageStage( self.stage.factory ) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) - return f'{self.previous.str(tab)}' \ - f'{tabulate(tab)}{hash_point_format(self.stage, tab)}' + return f'{await self.previous.str(tab)}' \ + f'{tabulate(tab)}{await hash_point_format(self.stage, tab)}' class StageStageFactory(RainbowFactory[StageStage[HeaderType, BaseStateType, StageType]]): @@ -148,23 +155,29 @@ class StateStage( self.state = state self.stage_factory = stage_factory - def verify( + async def verify( self, previous: NullableReference['StateStage[HeaderType, BaseStateType, StageType]'], header: HashPoint[HeaderType] ) -> bool: assert isinstance(previous, NullableReference) assert isinstance(header, HashPoint) - previous_stage: StageStage[HeaderType, BaseStateType, StageType] = self.previous.resolve() + previous_stage: StageStage[HeaderType, BaseStateType, StageType] = await self.previous.resolve() assert isinstance(previous_stage, StageStage) - return self.protocol.verify_state( - previous_stage.stage, - self.state - ) and previous_stage.verify( - previous, - header, - self.state.factory + assert_true( + await self.protocol.verify_state( + previous_stage.stage, + self.state + ) ) + assert_true( + await previous_stage.verify( + previous, + header, + self.state.factory + ) + ) + return True def points(self) -> Iterable[HashPoint]: return [self.previous, self.state] @@ -179,10 +192,10 @@ class StateStage( self.state.factory ) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) - return f'{hash_point_format(self.previous, tab)}' \ - f'{tabulate(tab)}{hash_point_format(self.state, tab)}' + return f'{await hash_point_format(self.previous, tab)}' \ + f'{tabulate(tab)}{await hash_point_format(self.state, tab)}' class StateStageFactory(RainbowFactory[StateStage[HeaderType, BaseStateType, StageType]]): diff --git a/rainbowadn/chain/stages/stageprotocol.py b/rainbowadn/chain/stages/stageprotocol.py index 7366998..4621a77 100644 --- a/rainbowadn/chain/stages/stageprotocol.py +++ b/rainbowadn/chain/stages/stageprotocol.py @@ -11,7 +11,7 @@ StageType = TypeVar('StageType') class StageProtocol(Generic[HeaderType, BaseStateType, StageType]): - def verify_header( + async def verify_header( self, previous: NullableReference[BaseStateType], header: HashPoint[HeaderType], @@ -19,14 +19,14 @@ class StageProtocol(Generic[HeaderType, BaseStateType, StageType]): ) -> bool: raise NotImplementedError - def verify_stage( + async def verify_stage( self, previous: HashPoint[StageType], stage: HashPoint[StageType] ) -> bool: raise NotImplementedError - def verify_state( + async def verify_state( self, stage: HashPoint[StageType], state: HashPoint[BaseStateType] diff --git a/rainbowadn/chain/stages/stagestateprotocol.py b/rainbowadn/chain/stages/stagestateprotocol.py index 73abff7..2bc7c12 100644 --- a/rainbowadn/chain/stages/stagestateprotocol.py +++ b/rainbowadn/chain/stages/stagestateprotocol.py @@ -2,6 +2,7 @@ from typing import Generic, TypeVar from rainbowadn.chain.stages.stage import StateStage from rainbowadn.chain.states.stateprotocol import StateProtocol +from rainbowadn.core.asserts import assert_true from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.nullability.nullablereference import NullableReference @@ -16,7 +17,7 @@ class StageStateProtocol( StateProtocol[HeaderType, StateStage[HeaderType, BaseStateType, StageType]], Generic[HeaderType, BaseStateType, StageType] ): - def verify( + async def verify( self, previous: NullableReference[StateStage[HeaderType, BaseStateType, StageType]], header: HashPoint[HeaderType], @@ -25,4 +26,5 @@ class StageStateProtocol( assert isinstance(previous, NullableReference) assert isinstance(header, HashPoint) assert isinstance(state, HashPoint) - return state.resolve().verify(previous, header) + assert_true(await (await state.resolve()).verify(previous, header)) + return True diff --git a/rainbowadn/chain/states/activestateprotocol.py b/rainbowadn/chain/states/activestateprotocol.py index 656db59..cd81930 100644 --- a/rainbowadn/chain/states/activestateprotocol.py +++ b/rainbowadn/chain/states/activestateprotocol.py @@ -1,6 +1,7 @@ from typing import TypeVar from rainbowadn.chain.states.stateprotocol import StateProtocol +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.nullability.nullablereference import NullableReference @@ -11,7 +12,7 @@ StateType = TypeVar('StateType') class ActiveStateProtocol(StateProtocol[HeaderType, StateType]): - def verify( + async def verify( self, previous: NullableReference[StateType], header: HashPoint[HeaderType], @@ -20,10 +21,10 @@ class ActiveStateProtocol(StateProtocol[HeaderType, StateType]): assert isinstance(previous, NullableReference) assert isinstance(header, HashPoint) assert isinstance(state, HashPoint) - assert state == self.derive(previous, header) + assert_eq(state, await self.derive(previous, header)) return True - def derive( + async def derive( self, previous: NullableReference[StateType], header: HashPoint[HeaderType], diff --git a/rainbowadn/chain/states/metareductionstateprotocol.py b/rainbowadn/chain/states/metareductionstateprotocol.py index 7a5858c..d827662 100644 --- a/rainbowadn/chain/states/metareductionstateprotocol.py +++ b/rainbowadn/chain/states/metareductionstateprotocol.py @@ -1,6 +1,7 @@ from typing import TypeVar from rainbowadn.chain.states.activestateprotocol import ActiveStateProtocol +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.nullability.nullablereference import NullableReference @@ -11,7 +12,7 @@ StateType = TypeVar('StateType') class MetaReductionStateProtocol(ActiveStateProtocol[HeaderType, StateType]): - def verify( + async def verify( self, previous: NullableReference[StateType], header: HashPoint[HeaderType], @@ -20,20 +21,20 @@ class MetaReductionStateProtocol(ActiveStateProtocol[HeaderType, StateType]): assert isinstance(previous, NullableReference) assert isinstance(header, HashPoint) assert isinstance(state, HashPoint) - assert state == self.derive(previous, header) + assert_eq(state, await self.derive(previous, header)) return True def _initial_state(self) -> HashPoint[StateType]: raise NotImplementedError - def _derive( + async def _derive( self, previous: HashPoint[StateType], header: HashPoint[HeaderType], ) -> HashPoint[StateType]: raise NotImplementedError - def derive( + async def derive( self, previous: NullableReference[StateType], header: HashPoint[HeaderType], @@ -45,4 +46,4 @@ class MetaReductionStateProtocol(ActiveStateProtocol[HeaderType, StateType]): else: previous_state: HashPoint[StateType] = previous.hashpoint() assert isinstance(previous_state, HashPoint) - return self._derive(previous_state, header) + return await self._derive(previous_state, header) diff --git a/rainbowadn/chain/states/stateprotocol.py b/rainbowadn/chain/states/stateprotocol.py index aefb6a4..352e362 100644 --- a/rainbowadn/chain/states/stateprotocol.py +++ b/rainbowadn/chain/states/stateprotocol.py @@ -10,7 +10,7 @@ StateType = TypeVar('StateType') class StateProtocol(Generic[HeaderType, StateType]): - def verify( + async def verify( self, previous: NullableReference[StateType], header: HashPoint[HeaderType], diff --git a/rainbowadn/core/asserts.py b/rainbowadn/core/asserts.py new file mode 100644 index 0000000..c9d2bbf --- /dev/null +++ b/rainbowadn/core/asserts.py @@ -0,0 +1,24 @@ +from typing import Optional, TypeVar + + +def assert_true(value: bool) -> bool: + assert value is True + return True + + +def assert_false(value: bool) -> bool: + assert value is False + return True + + +T = TypeVar('T') + + +def assert_none(value: Optional[T]) -> bool: + assert value is None + return True + + +def assert_eq(value: T, other: T) -> bool: + assert value == other + return True diff --git a/rainbowadn/core/extendableresolver.py b/rainbowadn/core/extendableresolver.py new file mode 100644 index 0000000..9c1b8fc --- /dev/null +++ b/rainbowadn/core/extendableresolver.py @@ -0,0 +1,20 @@ +import abc +from typing import TypeVar + +from rainbowadn.core.hashpoint import HashPoint +from rainbowadn.core.hashresolver import HashResolver +from rainbowadn.core.resolvermetaorigin import ResolverMetaOrigin + +Mentioned = TypeVar('Mentioned') + + +class ExtendableResolver(HashResolver, abc.ABC): + async def extend(self, hash_point: HashPoint[Mentioned]) -> 'ExtendableResolver': + raise NotImplementedError + + async def migrate(self, hash_point: HashPoint[Mentioned]) -> HashPoint[Mentioned]: + assert isinstance(hash_point, HashPoint) + return ResolverMetaOrigin(await self.extend(hash_point)).hash_point(hash_point.factory, hash_point.point) + + async def migrate_resolved(self, mentioned: Mentioned) -> Mentioned: + return await (await self.migrate(HashPoint.of(mentioned))).resolve() diff --git a/rainbowadn/core/hash_point_format.py b/rainbowadn/core/hash_point_format.py index 2d989bc..f6838de 100644 --- a/rainbowadn/core/hash_point_format.py +++ b/rainbowadn/core/hash_point_format.py @@ -1,15 +1,16 @@ from rainbowadn.core.hashpoint import HashPoint +from rainbowadn.core.mentionable import Mentionable from rainbowadn.core.recursivementionable import RecursiveMentionable __all__ = ('hash_point_format', 'tabulate',) -def hash_point_format(hash_point: HashPoint, tab: int) -> str: +async def hash_point_format(hash_point: HashPoint, tab: int) -> str: assert isinstance(hash_point, HashPoint) assert isinstance(tab, int) - value = hash_point.resolve() + value: Mentionable = await hash_point.resolve() if isinstance(value, RecursiveMentionable): - return value.str(tab) + return await value.str(tab) else: return str(value) diff --git a/rainbowadn/core/hashpoint.py b/rainbowadn/core/hashpoint.py index c50f102..0914421 100644 --- a/rainbowadn/core/hashpoint.py +++ b/rainbowadn/core/hashpoint.py @@ -1,6 +1,7 @@ import hashlib from typing import Generic, TypeVar +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.localorigin import LocalOrigin from rainbowadn.core.mentionable import Mentionable from rainbowadn.core.origin import Origin @@ -24,7 +25,7 @@ class HashPoint(Generic[Mentioned]): ): assert isinstance(point, bytes) assert isinstance(origin, Origin) - assert len(point) == self.HASH_LENGTH + assert_eq(len(point), self.HASH_LENGTH) self.point = point self.origin = origin self.factory = origin.factory @@ -46,7 +47,7 @@ class HashPoint(Generic[Mentioned]): assert isinstance(mentioned, Mentionable) topology_hash: bytes = mentioned.__topology_hash__() assert isinstance(topology_hash, bytes) - assert len(topology_hash) == cls.HASH_LENGTH + assert_eq(len(topology_hash), cls.HASH_LENGTH) return topology_hash + bytes(mentioned) @classmethod @@ -56,10 +57,10 @@ class HashPoint(Generic[Mentioned]): cls.hash(cls.bytes_of_mentioned(mentioned)), LocalOrigin(mentioned) ) - def resolve(self) -> Mentioned: - resolved = self.origin.resolve() + async def resolve(self) -> Mentioned: + resolved: Mentioned = await self.origin.resolve() assert isinstance(resolved, Mentionable) - assert self.point == self.hash(self.bytes_of_mentioned(resolved)) + assert_eq(self.point, self.hash(self.bytes_of_mentioned(resolved))) return resolved def __eq__(self, other): diff --git a/rainbowadn/core/hashresolver.py b/rainbowadn/core/hashresolver.py index 011edd9..850194a 100644 --- a/rainbowadn/core/hashresolver.py +++ b/rainbowadn/core/hashresolver.py @@ -2,5 +2,5 @@ __all__ = ('HashResolver',) class HashResolver: - def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: + async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: raise NotImplementedError diff --git a/rainbowadn/core/localmetaorigin.py b/rainbowadn/core/localmetaorigin.py index 3ae4d0f..46eb247 100644 --- a/rainbowadn/core/localmetaorigin.py +++ b/rainbowadn/core/localmetaorigin.py @@ -1,5 +1,6 @@ from typing import Generic, TypeVar +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.metaorigin import MetaOrigin from rainbowadn.core.origin import Origin @@ -18,5 +19,5 @@ class LocalMetaOrigin(MetaOrigin[Mentioned], Generic[Mentioned]): def origin(self, factory: RainbowFactory[Mentioned], point: bytes) -> Origin[Mentioned]: assert isinstance(factory, RainbowFactory) assert isinstance(point, bytes) - assert len(point) == HashPoint.HASH_LENGTH + assert_eq(len(point), HashPoint.HASH_LENGTH) return self._origin diff --git a/rainbowadn/core/localorigin.py b/rainbowadn/core/localorigin.py index f92e236..520970a 100644 --- a/rainbowadn/core/localorigin.py +++ b/rainbowadn/core/localorigin.py @@ -14,5 +14,5 @@ class LocalOrigin(Origin[Mentioned], Generic[Mentioned]): super().__init__(value.__factory__()) self.value: Mentioned = value - def resolve(self) -> Mentioned: + async def resolve(self) -> Mentioned: return self.value diff --git a/rainbowadn/core/metaorigin.py b/rainbowadn/core/metaorigin.py index 01e306a..751181d 100644 --- a/rainbowadn/core/metaorigin.py +++ b/rainbowadn/core/metaorigin.py @@ -1,5 +1,6 @@ from typing import Generic, TypeVar +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.origin import Origin from rainbowadn.core.rainbow_factory import RainbowFactory @@ -16,5 +17,5 @@ class MetaOrigin(Generic[Mentioned]): def hash_point(self, factory: RainbowFactory[Mentioned], point: bytes) -> HashPoint[Mentioned]: assert isinstance(factory, RainbowFactory) assert isinstance(point, bytes) - assert len(point) == HashPoint.HASH_LENGTH + assert_eq(len(point), HashPoint.HASH_LENGTH) return HashPoint(point, self.origin(factory, point)) diff --git a/rainbowadn/core/nullability/nullablereference.py b/rainbowadn/core/nullability/nullablereference.py index 2f4bce2..3662a8b 100644 --- a/rainbowadn/core/nullability/nullablereference.py +++ b/rainbowadn/core/nullability/nullablereference.py @@ -48,11 +48,11 @@ class NullableReference(RecursiveMentionable, Generic[Referenced]): def off(cls, value: Referenced) -> 'NullableReference[Referenced]': return cls.of(HashPoint.of(value)) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: if self.null(): return f'-' else: - return f'{hash_point_format(self.hashpoint(), tab)}' + return f'{await hash_point_format(self.hashpoint(), tab)}' def __eq__(self, other): if isinstance(other, NullableReference): @@ -67,9 +67,9 @@ class NullableReference(RecursiveMentionable, Generic[Referenced]): assert not self.null() return self.reference.resolve() - def resolve(self) -> Referenced: + async def resolve(self) -> Referenced: assert not self.null() - return self.hashpoint().resolve() + return await self.hashpoint().resolve() class NullableReferenceFactory(RainbowFactory[NullableReference[Referenced]], Generic[Referenced]): diff --git a/rainbowadn/core/origin.py b/rainbowadn/core/origin.py index 1429e64..691409e 100644 --- a/rainbowadn/core/origin.py +++ b/rainbowadn/core/origin.py @@ -11,5 +11,5 @@ class Origin(Generic[Mentioned]): def __init__(self, factory: RainbowFactory[Mentioned]): self.factory = factory - def resolve(self) -> Mentioned: + async def resolve(self) -> Mentioned: raise NotImplementedError diff --git a/rainbowadn/core/recursivementionable.py b/rainbowadn/core/recursivementionable.py index 60eaab5..4a7a02c 100644 --- a/rainbowadn/core/recursivementionable.py +++ b/rainbowadn/core/recursivementionable.py @@ -11,7 +11,7 @@ class RecursiveMentionable(Mentionable, abc.ABC): def points(self) -> Iterable[HashPoint]: raise NotImplementedError - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) return f'(recursive {self.__class__.__name__})' diff --git a/rainbowadn/core/resolvermetaorigin.py b/rainbowadn/core/resolvermetaorigin.py index 322d6dc..055050f 100644 --- a/rainbowadn/core/resolvermetaorigin.py +++ b/rainbowadn/core/resolvermetaorigin.py @@ -1,5 +1,6 @@ from typing import Generic, TypeVar +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.metaorigin import MetaOrigin @@ -20,12 +21,5 @@ class ResolverMetaOrigin(MetaOrigin[Mentioned], Generic[Mentioned]): def origin(self, factory: RainbowFactory[Mentioned], point: bytes) -> Origin[Mentioned]: assert isinstance(factory, RainbowFactory) assert isinstance(point, bytes) - assert len(point) == HashPoint.HASH_LENGTH + assert_eq(len(point), HashPoint.HASH_LENGTH) return ResolverOrigin(factory, point, self.resolver) - - def migrate(self, hash_point: HashPoint[Mentioned]) -> HashPoint[Mentioned]: - assert isinstance(hash_point, HashPoint) - return self.hash_point(hash_point.factory, hash_point.point) - - def migrate_resolved(self, mentioned: Mentioned) -> Mentioned: - return self.migrate(HashPoint.of(mentioned)).resolve() diff --git a/rainbowadn/core/resolverorigin.py b/rainbowadn/core/resolverorigin.py index 1aa067c..3a4d407 100644 --- a/rainbowadn/core/resolverorigin.py +++ b/rainbowadn/core/resolverorigin.py @@ -1,5 +1,6 @@ from typing import Generic, TypeVar +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.mentionable import Mentionable @@ -26,14 +27,14 @@ class ResolverOrigin(Origin[Mentioned], Generic[Mentioned]): self.resolver = resolver super().__init__(factory) - def resolve(self) -> Mentioned: - resolved, resolver = self.resolver.resolve(self.point) + async def resolve(self) -> Mentioned: + resolved, resolver = await self.resolver.resolve(self.point) assert isinstance(resolved, bytes) assert isinstance(resolver, HashResolver) mentioned: Mentioned = self.factory.from_bytes(resolved[HashPoint.HASH_LENGTH:], resolver) assert isinstance(mentioned, Mentionable) - assert mentioned.__topology_hash__() == resolved[:HashPoint.HASH_LENGTH] - assert self.point == HashPoint.hash(HashPoint.bytes_of_mentioned(mentioned)) + assert_eq(mentioned.__topology_hash__(), resolved[:HashPoint.HASH_LENGTH]) + assert_eq(self.point, HashPoint.hash(HashPoint.bytes_of_mentioned(mentioned))) return mentioned def hash_point(self) -> HashPoint[Mentioned]: diff --git a/rainbowadn/data/collection/array/array.py b/rainbowadn/data/collection/array/array.py index cdf45d5..5c29366 100644 --- a/rainbowadn/data/collection/array/array.py +++ b/rainbowadn/data/collection/array/array.py @@ -32,11 +32,11 @@ class Array(RecursiveMentionable, Generic[ElementType]): def __factory__(self) -> RainbowFactory['Array']: return ArrayFactory(self.factory) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) formatted = f'(' for hash_point in self.array: - formatted += f'{tabulate(tab + 1)}{hash_point_format(hash_point, tab + 1)}' + formatted += f'{tabulate(tab + 1)}{await hash_point_format(hash_point, tab + 1)}' return f'{formatted}' \ f'{tabulate(tab)})' diff --git a/rainbowadn/data/collection/keymetadata.py b/rainbowadn/data/collection/keymetadata.py index a531a88..46a8fec 100644 --- a/rainbowadn/data/collection/keymetadata.py +++ b/rainbowadn/data/collection/keymetadata.py @@ -29,10 +29,10 @@ class KeyMetadata(Keyed[ActiveKeyType], Generic[ActiveKeyType, MetaDataType]): def __factory__(self) -> RainbowFactory['KeyMetadata[ActiveKeyType, MetaDataType]']: return KeyMetadataFactory(self.key.factory, self.metadata.factory) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) - return f'{hash_point_format(self.key, tab)}' \ - f'{tabulate(tab)}{hash_point_format(self.metadata, tab)}' + return f'{await hash_point_format(self.key, tab)}' \ + f'{tabulate(tab)}{await hash_point_format(self.metadata, tab)}' class KeyMetadataFactory( diff --git a/rainbowadn/data/collection/pair.py b/rainbowadn/data/collection/pair.py index 1b805ff..178b874 100644 --- a/rainbowadn/data/collection/pair.py +++ b/rainbowadn/data/collection/pair.py @@ -32,11 +32,11 @@ class Pair( def __factory__(self) -> RainbowFactory['Pair[E0Type, E1Type]']: return PairFactory(self.element0.factory, self.element1.factory) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) return f'(pair)' \ - f'{tabulate(tab)}{hash_point_format(self.element0, tab)}' \ - f'{tabulate(tab)}{hash_point_format(self.element1, tab)}' + f'{tabulate(tab)}{await hash_point_format(self.element0, tab)}' \ + f'{tabulate(tab)}{await hash_point_format(self.element1, tab)}' class PairFactory( diff --git a/rainbowadn/data/collection/stack/stack.py b/rainbowadn/data/collection/stack/stack.py index f5702bb..30f2743 100644 --- a/rainbowadn/data/collection/stack/stack.py +++ b/rainbowadn/data/collection/stack/stack.py @@ -1,4 +1,4 @@ -from typing import Generic, Iterable, TypeVar +from typing import AsyncIterable, Generic, Iterable, TypeVar from rainbowadn.core.hash_point_format import hash_point_format, tabulate from rainbowadn.core.hashpoint import HashPoint @@ -35,10 +35,10 @@ class Stack(RecursiveMentionable, Generic[ElementType]): def __bytes__(self): return bytes(self.previous) + bytes(self.element) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) - return f'{self.previous.str(tab)}' \ - f'{tabulate(tab)}{hash_point_format(self.element, tab)}' + return f'{await self.previous.str(tab)}' \ + f'{tabulate(tab)}{await hash_point_format(self.element, tab)}' @classmethod def of( @@ -69,17 +69,18 @@ class Stack(RecursiveMentionable, Generic[ElementType]): return cls.of(factory, map(HashPoint.of, elements)) @classmethod - def iter( + async def iter( cls, reference: NullableReference['Stack[ElementType]'] - ) -> Iterable[HashPoint[ElementType]]: + ) -> AsyncIterable[HashPoint[ElementType]]: assert isinstance(reference, NullableReference) if reference.null(): pass else: - stack: Stack[ElementType] = reference.resolve() + stack: Stack[ElementType] = await reference.resolve() yield stack.element - yield from cls.iter(stack.previous) + async for element in cls.iter(stack.previous): + yield element class StackFactory(RainbowFactory[Stack[ElementType]], Generic[ElementType]): diff --git a/rainbowadn/data/collection/trees/binary/actions/binarytreeaction.py b/rainbowadn/data/collection/trees/binary/actions/binarytreeaction.py index dd048eb..baf0a43 100644 --- a/rainbowadn/data/collection/trees/binary/actions/binarytreeaction.py +++ b/rainbowadn/data/collection/trees/binary/actions/binarytreeaction.py @@ -12,31 +12,25 @@ ActionType = TypeVar('ActionType') class BinaryTreeAction(Generic[ActiveKeyType, MetaDataType, TreeType, ActionType]): - def on( + async def on( self, protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], tree: TreeType ) -> ActionType: - if (split := protocol.split(tree)) is None: - return self.on_null(protocol, tree) + if (split := await protocol.split(tree)) is None: + return await self.on_null(protocol, tree) else: - return self.on_split(BinaryTreeCase(protocol, split, tree)) + return await self.on_split(BinaryTreeCase(protocol, split, tree)) - def on_null( + async def on_null( self, protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], tree: TreeType ) -> ActionType: raise NotImplementedError - def on_split( + async def on_split( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] ) -> ActionType: raise NotImplementedError - - def per( - self: 'BinaryTreeAction[ActiveKeyType, MetaDataType, TreeType, ActionType]', - _protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType] - ) -> 'BinaryTreeAction[ActiveKeyType, MetaDataType, TreeType, ActionType]': - return self diff --git a/rainbowadn/data/collection/trees/binary/actions/compareaction.py b/rainbowadn/data/collection/trees/binary/actions/compareaction.py index 67ed454..110256f 100644 --- a/rainbowadn/data/collection/trees/binary/actions/compareaction.py +++ b/rainbowadn/data/collection/trees/binary/actions/compareaction.py @@ -23,36 +23,36 @@ class CompareAction( assert isinstance(key, HashPoint) self.key = key - def on_split( + async def on_split( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] ) -> ActionType: assert isinstance(case, BinaryTreeCase) - comparison: Comparison = case.protocol.comparator.compare(case.split.key, self.key) + comparison: Comparison = await case.protocol.comparator.compare(case.split.key, self.key) assert isinstance(comparison, Comparison) if isinstance(comparison, Equal): - return self.on_equal(case, comparison) + return await self.on_equal(case, comparison) elif isinstance(comparison, Left): - return self.on_left(case) + return await self.on_left(case) elif isinstance(comparison, Right): - return self.on_right(case) + return await self.on_right(case) else: raise TypeError - def on_equal( + async def on_equal( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType], equal: Equal ) -> ActionType: raise NotImplementedError - def on_left( + async def on_left( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] ) -> ActionType: raise NotImplementedError - def on_right( + async def on_right( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] ) -> ActionType: diff --git a/rainbowadn/data/collection/trees/binary/actions/stdactions.py b/rainbowadn/data/collection/trees/binary/actions/stdactions.py index 51bca77..cf6aadc 100644 --- a/rainbowadn/data/collection/trees/binary/actions/stdactions.py +++ b/rainbowadn/data/collection/trees/binary/actions/stdactions.py @@ -22,34 +22,42 @@ class AddAction( ], Generic[ActiveKeyType, MetaDataType, TreeType] ): - def on_equal( + async def on_equal( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType], equal: Equal ) -> TreeType: if isinstance(equal, Replace): - return case.protocol.tree(case.split.treel, case.split.treer, self.key) + return await case.protocol.tree(case.split.treel, case.split.treer, self.key) else: raise TypeError - def on_left( + async def on_left( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] ) -> TreeType: - return case.protocol.tree(self.on(case.protocol, case.split.treel), case.split.treer, case.split.key) + return await case.protocol.tree( + await self.on(case.protocol, case.split.treel), + case.split.treer, + case.split.key + ) - def on_right( + async def on_right( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] ) -> TreeType: - return case.protocol.tree(case.split.treel, self.on(case.protocol, case.split.treer), case.split.key) + return await case.protocol.tree( + case.split.treel, + await self.on(case.protocol, case.split.treer), + case.split.key + ) - def on_null( + async def on_null( self, protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], tree: TreeType ) -> TreeType: - return protocol.tree(tree, tree, self.key) + return await protocol.tree(tree, tree, self.key) class MergeAction( @@ -64,22 +72,22 @@ class MergeAction( def __init__(self, treer: TreeType): self.treer = treer - def on_null( + async def on_null( self, protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], tree: TreeType ) -> TreeType: return self.treer - def on_split( + async def on_split( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] ) -> TreeType: protocol = case.protocol split = case.split - return protocol.tree( + return await protocol.tree( split.treel, - MergeAction(self.treer).on(protocol, split.treer), + await MergeAction(self.treer).on(protocol, split.treer), split.key ) @@ -93,26 +101,34 @@ class RemoveAction( ], Generic[ActiveKeyType, MetaDataType, TreeType] ): - def on_equal( + async def on_equal( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType], equal: Equal ) -> TreeType: - return MergeAction(case.split.treer).on(case.protocol, case.split.treel) + return await MergeAction(case.split.treer).on(case.protocol, case.split.treel) - def on_left( + async def on_left( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] ) -> TreeType: - return case.protocol.tree(self.on(case.protocol, case.split.treel), case.split.treer, case.split.key) + return await case.protocol.tree( + await self.on(case.protocol, case.split.treel), + case.split.treer, + case.split.key + ) - def on_right( + async def on_right( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] ) -> TreeType: - return case.protocol.tree(case.split.treel, self.on(case.protocol, case.split.treer), case.split.key) + return await case.protocol.tree( + case.split.treel, + await self.on(case.protocol, case.split.treer), + case.split.key + ) - def on_null( + async def on_null( self, protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], tree: TreeType @@ -129,26 +145,26 @@ class ContainsAction( ], Generic[ActiveKeyType, MetaDataType, TreeType] ): - def on_equal( + async def on_equal( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType], equal: Equal ) -> bool: return True - def on_left( + async def on_left( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] ) -> bool: - return self.on(case.protocol, case.split.treel) + return await self.on(case.protocol, case.split.treel) - def on_right( + async def on_right( self, case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] ) -> bool: - return self.on(case.protocol, case.split.treer) + return await self.on(case.protocol, case.split.treer) - def on_null( + async def on_null( self, protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], tree: TreeType diff --git a/rainbowadn/data/collection/trees/binary/actions/symmetric.py b/rainbowadn/data/collection/trees/binary/actions/symmetric.py index 0aa1463..d904616 100644 --- a/rainbowadn/data/collection/trees/binary/actions/symmetric.py +++ b/rainbowadn/data/collection/trees/binary/actions/symmetric.py @@ -34,7 +34,7 @@ class Symmetric( ) -> TreeType: raise NotImplementedError - def tree( + async def tree( self, inner: TreeType, outer: TreeType, @@ -56,13 +56,13 @@ class InnerOuter(Symmetric): ) -> TreeType: return split.treer - def tree( + async def tree( self, inner: TreeType, outer: TreeType, key: HashPoint[ActiveKeyType] ) -> TreeType: - return self.case.protocol.tree(inner, outer, key) + return await self.case.protocol.tree(inner, outer, key) class OuterInner(Symmetric): @@ -78,10 +78,10 @@ class OuterInner(Symmetric): ) -> TreeType: return split.treel - def tree( + async def tree( self, inner: TreeType, outer: TreeType, key: HashPoint[ActiveKeyType] ) -> TreeType: - return self.case.protocol.tree(outer, inner, key) + return await self.case.protocol.tree(outer, inner, key) diff --git a/rainbowadn/data/collection/trees/binary/activebinarytree.py b/rainbowadn/data/collection/trees/binary/activebinarytree.py index ce66f8e..5995997 100644 --- a/rainbowadn/data/collection/trees/binary/activebinarytree.py +++ b/rainbowadn/data/collection/trees/binary/activebinarytree.py @@ -65,17 +65,17 @@ class ActiveBinaryTree( reference ) - def add(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': + async def add(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': assert isinstance(key, HashPoint) - return AddAction(key).on(self.creation, self) + return await AddAction(key).on(self.creation, self) - def remove(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': + async def remove(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': assert isinstance(key, HashPoint) - return RemoveAction(key).on(self.creation, self) + return await RemoveAction(key).on(self.creation, self) - def contains(self, key: HashPoint[ActiveKeyType]) -> bool: + async def contains(self, key: HashPoint[ActiveKeyType]) -> bool: assert isinstance(key, HashPoint) - return ContainsAction(key).on(self.creation, self) + return await ContainsAction(key).on(self.creation, self) def loose(self) -> CollectionInterface[ BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] @@ -90,7 +90,7 @@ class ActiveCreationProtocol( ActiveBinaryTree[ActiveKeyType, MetaDataType] ] ): - def split( + async def split( self, tree: ActiveBinaryTree[ActiveKeyType, MetaDataType] ) -> Optional[ @@ -104,15 +104,15 @@ class ActiveCreationProtocol( if tree.reference.null(): return None else: - resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = tree.reference.resolve() + resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = await tree.reference.resolve() assert isinstance(resolved, BinaryTree) - key_metadata: KeyMetadata[ActiveKeyType, MetaDataType] = resolved.key.resolve() + key_metadata: KeyMetadata[ActiveKeyType, MetaDataType] = await resolved.key.resolve() assert isinstance(key_metadata, KeyMetadata) return BinaryTreeSplit( tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer) ) - def _tree( + async def _tree( self, treel: ActiveBinaryTree, treer: ActiveBinaryTree, @@ -127,7 +127,7 @@ class ActiveCreationProtocol( BinaryTree( treel.reference, treer.reference, - HashPoint.of(KeyMetadata(key, self.protocol.metadata(treel, treer, key, self))) + HashPoint.of(KeyMetadata(key, await self.protocol.metadata(treel, treer, key, self))) ) ) ) diff --git a/rainbowadn/data/collection/trees/binary/avl.py b/rainbowadn/data/collection/trees/binary/avl.py index 9c89f0b..5006963 100644 --- a/rainbowadn/data/collection/trees/binary/avl.py +++ b/rainbowadn/data/collection/trees/binary/avl.py @@ -18,7 +18,7 @@ class AVL(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]): def empty_metadata(self) -> HashPoint[Integer]: return HashPoint.of(Integer(0)) - def metadata( + async def metadata( self, treel: TreeType, treer: TreeType, @@ -26,85 +26,90 @@ class AVL(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]): protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType] ) -> HashPoint[Integer]: return HashPoint.of( - Integer(1 + max(self.height(treel, protocol), self.height(treer, protocol))) + Integer(1 + max(await self.height(treel, protocol), await self.height(treer, protocol))) ) @classmethod - def height( + async def height( cls, tree: TreeType, protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType] ) -> int: - return HeightAction().on(protocol, tree) + return await HeightAction().on(protocol, tree) - def balance( + async def balance( self, tree: TreeType, protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType] ) -> TreeType: - return BalanceAction().on(protocol, tree) + return await BalanceAction().on(protocol, tree) class HeightAction( BinaryTreeAction[ActiveKeyType, Integer, TreeType, int], Generic[ActiveKeyType, TreeType] ): - def on_null( + async def on_null( self, protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType], tree: TreeType ) -> int: return 0 - def on_split( + async def on_split( self, case: BinaryTreeCase[ActiveKeyType, Integer, TreeType] ) -> int: - return case.split.metadata.resolve().integer + metadata: Integer = await case.split.metadata.resolve() + return metadata.integer class BalanceAction( BinaryTreeAction[ActiveKeyType, Integer, TreeType, TreeType], Generic[ActiveKeyType, TreeType] ): - def on_null( + async def on_null( self, protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType], tree: TreeType ) -> TreeType: return tree - def on_split( + async def on_split( self, case: BinaryTreeCase[ActiveKeyType, Integer, TreeType] ) -> TreeType: split, protocol = case.split, case.protocol - delta = AVL.height(split.treel, protocol) - AVL.height(split.treer, protocol) + delta = (await AVL.height(split.treel, protocol)) - (await AVL.height(split.treer, protocol)) assert isinstance(delta, int) if delta < -1: - return self.on_symmetric(InnerOuter(case)) + return await self.on_symmetric(InnerOuter(case)) elif delta > 1: - return self.on_symmetric(OuterInner(case)) + return await self.on_symmetric(OuterInner(case)) else: return case.tree @classmethod - def on_symmetric( + async def on_symmetric( cls, symmetric: Symmetric[ActiveKeyType, Integer, TreeType] ) -> TreeType: protocol, split = symmetric.case.protocol, symmetric.case.split - splito = protocol.fsplit(symmetric.outer(split)) - if AVL.height(symmetric.inner(splito), protocol) > AVL.height(symmetric.outer(splito), protocol): - splitoi = protocol.fsplit(symmetric.inner(splito)) - return symmetric.tree( - symmetric.tree(symmetric.inner(split), symmetric.inner(splitoi), split.key), - symmetric.tree(symmetric.outer(splitoi), symmetric.outer(splito), splito.key), + splito = await protocol.fsplit(symmetric.outer(split)) + if ( + (await AVL.height(symmetric.inner(splito), protocol)) + > + (await AVL.height(symmetric.outer(splito), protocol)) + ): + splitoi = await protocol.fsplit(symmetric.inner(splito)) + return await symmetric.tree( + await symmetric.tree(symmetric.inner(split), symmetric.inner(splitoi), split.key), + await symmetric.tree(symmetric.outer(splitoi), symmetric.outer(splito), splito.key), splitoi.key ) else: - return symmetric.tree( - symmetric.tree(symmetric.inner(split), symmetric.inner(splito), split.key), + return await symmetric.tree( + await symmetric.tree(symmetric.inner(split), symmetric.inner(splito), split.key), symmetric.outer(splito), splito.key ) diff --git a/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py b/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py index d7fb820..9f925d6 100644 --- a/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py +++ b/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py @@ -25,15 +25,15 @@ class BalancedTreeCreationProtocol( self.protocol = protocol super().__init__(protocol.comparator) - def _tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType: + async def _tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType: raise NotImplementedError - def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType: + async def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType: assert isinstance(key, HashPoint) - return self.protocol.balance( - self._tree( - self.protocol.balance(treel, self), - self.protocol.balance(treer, self), + return await self.protocol.balance( + await self._tree( + await self.protocol.balance(treel, self), + await self.protocol.balance(treer, self), key ), self diff --git a/rainbowadn/data/collection/trees/binary/binarytree.py b/rainbowadn/data/collection/trees/binary/binarytree.py index b8b76fd..8e38405 100644 --- a/rainbowadn/data/collection/trees/binary/binarytree.py +++ b/rainbowadn/data/collection/trees/binary/binarytree.py @@ -40,11 +40,11 @@ class BinaryTree(RecursiveMentionable, Generic[TreeKeyType]): def __bytes__(self): return bytes(self.treel) + bytes(self.treer) + bytes(self.key) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) - return f'{self.treel.str(tab)}' \ - f'{tabulate(tab)}{hash_point_format(self.key, tab)}' \ - f'{tabulate(tab)}{self.treer.str(tab)}' + return f'{await self.treel.str(tab)}' \ + f'{tabulate(tab)}{await hash_point_format(self.key, tab)}' \ + f'{tabulate(tab)}{await self.treer.str(tab)}' class BinaryTreeFactory(RainbowFactory[BinaryTree[TreeKeyType]], Generic[TreeKeyType]): diff --git a/rainbowadn/data/collection/trees/binary/binarytreebalancingprotocol.py b/rainbowadn/data/collection/trees/binary/binarytreebalancingprotocol.py index aa284f3..7ce4907 100644 --- a/rainbowadn/data/collection/trees/binary/binarytreebalancingprotocol.py +++ b/rainbowadn/data/collection/trees/binary/binarytreebalancingprotocol.py @@ -22,7 +22,7 @@ class BinaryTreeBalancingProtocol(Generic[ActiveKeyType, MetaDataType, TreeType] def empty_metadata(self) -> HashPoint[MetaDataType]: raise NotImplementedError - def metadata( + async def metadata( self, treel: TreeType, treer: TreeType, @@ -31,7 +31,7 @@ class BinaryTreeBalancingProtocol(Generic[ActiveKeyType, MetaDataType, TreeType] ) -> HashPoint[MetaDataType]: raise NotImplementedError - def balance( + async def balance( self, tree: TreeType, protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType] diff --git a/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py b/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py index 2161324..962ba33 100644 --- a/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py +++ b/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py @@ -15,18 +15,18 @@ class BinaryTreeCreationProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]) def __init__(self, comparator: Comparator[ActiveKeyType]): self.comparator = comparator - def split(self, tree: TreeType) -> Optional[ + async def split(self, tree: TreeType) -> Optional[ BinaryTreeSplit[ActiveKeyType, MetaDataType, TreeType] ]: """result of this method is supposed to be used right after the call, therefore all values are resolved""" raise NotImplementedError - def fsplit(self, tree: TreeType) -> BinaryTreeSplit[ + async def fsplit(self, tree: TreeType) -> BinaryTreeSplit[ ActiveKeyType, MetaDataType, TreeType ]: - split = self.split(tree) + split: Optional[BinaryTreeSplit[ActiveKeyType, MetaDataType, TreeType]] = await self.split(tree) assert split is not None return split - def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType: + async def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType: raise NotImplementedError diff --git a/rainbowadn/data/collection/trees/comparison/comparator.py b/rainbowadn/data/collection/trees/comparison/comparator.py index 536d294..d483479 100644 --- a/rainbowadn/data/collection/trees/comparison/comparator.py +++ b/rainbowadn/data/collection/trees/comparison/comparator.py @@ -47,5 +47,5 @@ KeyType = TypeVar('KeyType') class Comparator(Generic[KeyType]): - def compare(self, original: HashPoint[KeyType], key: HashPoint[KeyType]) -> Comparison: + async def compare(self, original: HashPoint[KeyType], key: HashPoint[KeyType]) -> Comparison: raise NotImplementedError diff --git a/rainbowadn/data/collection/trees/comparison/hashcomparator.py b/rainbowadn/data/collection/trees/comparison/hashcomparator.py index 25aad59..aa07d95 100644 --- a/rainbowadn/data/collection/trees/comparison/hashcomparator.py +++ b/rainbowadn/data/collection/trees/comparison/hashcomparator.py @@ -10,7 +10,7 @@ KeyType = TypeVar('KeyType') class HashComparator(ProtocolComparator[KeyType], Generic[KeyType]): - def compare(self, original: HashPoint[KeyType], key: HashPoint[KeyType]) -> Comparison: + async def compare(self, original: HashPoint[KeyType], key: HashPoint[KeyType]) -> Comparison: assert isinstance(original, HashPoint) assert isinstance(key, HashPoint) if key.point < original.point: diff --git a/rainbowadn/data/collection/trees/comparison/keyedcomparator.py b/rainbowadn/data/collection/trees/comparison/keyedcomparator.py index 4cf121c..070435a 100644 --- a/rainbowadn/data/collection/trees/comparison/keyedcomparator.py +++ b/rainbowadn/data/collection/trees/comparison/keyedcomparator.py @@ -17,14 +17,14 @@ class KeyedComparator( self.comparator = comparator super().__init__() - def compare( + async def compare( self, original: HashPoint[Keyed[ComparatorKeyType]], key: HashPoint[Keyed[ComparatorKeyType]] ) -> Comparison: assert isinstance(original, HashPoint) assert isinstance(key, HashPoint) - return self.comparator.compare( - original.resolve().key, - key.resolve().key, + return await self.comparator.compare( + (await original.resolve()).key, + (await key.resolve()).key, ) diff --git a/rainbowadn/data/collection/trees/comparison/plaincomparator.py b/rainbowadn/data/collection/trees/comparison/plaincomparator.py index 5c855d1..77845d2 100644 --- a/rainbowadn/data/collection/trees/comparison/plaincomparator.py +++ b/rainbowadn/data/collection/trees/comparison/plaincomparator.py @@ -7,12 +7,12 @@ __all__ = ('PlainComparator',) class PlainComparator(ProtocolComparator[Plain]): - def compare(self, original: HashPoint[Plain], key: HashPoint[Plain]) -> Comparison: + async def compare(self, original: HashPoint[Plain], key: HashPoint[Plain]) -> Comparison: assert isinstance(original, HashPoint) assert isinstance(key, HashPoint) - original_value: Plain = original.resolve() + original_value: Plain = await original.resolve() assert isinstance(original_value, Plain) - key_value: Plain = key.resolve() + key_value: Plain = await key.resolve() assert isinstance(key_value, Plain) if key_value.source < original_value.source: return Left() diff --git a/rainbowadn/encryption/encrypted.py b/rainbowadn/encryption/encrypted.py index ba23ab3..ab488c5 100644 --- a/rainbowadn/encryption/encrypted.py +++ b/rainbowadn/encryption/encrypted.py @@ -3,6 +3,7 @@ from typing import Generic, Iterable, TypeVar from nacl.bindings import crypto_hash_sha256 from nacl.secret import SecretBox +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.mentionable import Mentionable @@ -43,15 +44,17 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]): return self.resolution @classmethod - def encrypt(cls, decrypted: EncryptedType, key: bytes) -> 'Encrypted[EncryptedType]': + async def encrypt(cls, decrypted: EncryptedType, key: bytes) -> 'Encrypted[EncryptedType]': assert isinstance(key, bytes) hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else () - resolution = tuple( - cls.encrypt_hashpoint(hashpoint, key) - for - hashpoint - in - hashpoints + resolution: tuple[HashPoint[Encrypted[EncryptedType]], ...] = tuple( + [ + await cls.encrypt_hashpoint(hashpoint, key) + for + hashpoint + in + hashpoints + ] ) return cls.construct( key, @@ -61,7 +64,7 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]): ) @classmethod - def encrypt_hashpoint( + async def encrypt_hashpoint( cls, hashpoint: HashPoint[EncryptedType], key: bytes ) -> HashPoint['Encrypted[EncryptedType]']: assert isinstance(hashpoint, HashPoint) @@ -75,7 +78,7 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]): resolver.mapping[hashpoint.point], key ).hash_point() - return HashPoint.of(cls.encrypt(hashpoint.resolve(), key)) + return HashPoint.of(await cls.encrypt(await hashpoint.resolve(), key)) @classmethod def construct( @@ -129,7 +132,7 @@ class EncryptedFactory(RainbowFactory[Encrypted[EncryptedType]], Generic[Encrypt resolver, ) hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else () - assert len(hashpoints) == resolution_size + assert_eq(len(hashpoints), resolution_size) resolution: tuple[HashPoint[Encrypted], ...] = tuple( ResolverOrigin( EncryptedFactory( @@ -155,9 +158,9 @@ class EncryptedResolver(HashResolver): self.mapping = mapping self.key = key - def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: + async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: assert isinstance(point, bytes) - encrypted = self.mapping[point].resolve() + encrypted: Encrypted = await self.mapping[point].resolve() return HashPoint.bytes_of_mentioned(encrypted.decrypted), EncryptedResolver(encrypted.mapping, self.key) @@ -171,10 +174,10 @@ class ShortcutOrigin(Origin[Encrypted[EncryptedType]], Generic[EncryptedType]): self.hashpoint = hashpoint super().__init__(self.factory) - def resolve(self) -> Encrypted[EncryptedType]: - encrypted = self.hashpoint.resolve() - encrypted = self.factory.from_bytes(bytes(encrypted), ShortcutResolver(encrypted)) - assert HashPoint.of(encrypted) == self.hashpoint + async def resolve(self) -> Encrypted[EncryptedType]: + source: Encrypted = await self.hashpoint.resolve() + encrypted: Encrypted[EncryptedType] = self.factory.from_bytes(bytes(source), ShortcutResolver(source)) + assert_eq(HashPoint.of(encrypted), self.hashpoint) return encrypted def hash_point(self) -> HashPoint[Encrypted[EncryptedType]]: @@ -191,9 +194,9 @@ class ShortcutResolver(HashResolver): hashpoint.point: hashpoint for hashpoint in encrypted.resolution } - def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: + async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: assert isinstance(point, bytes) - resolved: Encrypted = self.mapping[point].resolve() + resolved: Encrypted = await self.mapping[point].resolve() return ( HashPoint.bytes_of_mentioned(resolved), ShortcutResolver(resolved) diff --git a/rainbowadn/testing/dictresolver.py b/rainbowadn/testing/dictresolver.py index b73a5d2..cbe3010 100644 --- a/rainbowadn/testing/dictresolver.py +++ b/rainbowadn/testing/dictresolver.py @@ -1,28 +1,33 @@ from collections import OrderedDict from typing import MutableMapping +from rainbowadn.core.extendableresolver import ExtendableResolver, Mentioned from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.mentionable import Mentionable from rainbowadn.core.recursivementionable import RecursiveMentionable -class DictResolver(HashResolver): +class DictResolver(ExtendableResolver): def __init__(self): self.table: MutableMapping[bytes, bytes] = OrderedDict() - def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: + async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: assert isinstance(point, bytes) return self.table[point], self - def save(self, hash_point: HashPoint) -> None: + async def save(self, hash_point: HashPoint) -> None: assert isinstance(hash_point, HashPoint) if hash_point.point in self.table: pass else: - value: Mentionable = hash_point.resolve() + value: Mentionable = await hash_point.resolve() assert isinstance(value, Mentionable) self.table[hash_point.point] = HashPoint.bytes_of_mentioned(value) if isinstance(value, RecursiveMentionable): for hash_point in value.points(): - self.save(hash_point) + await self.save(hash_point) + + async def extend(self, hash_point: HashPoint[Mentioned]) -> 'ExtendableResolver': + await self.save(hash_point) + return self diff --git a/rainbowadn/testing/failresolver.py b/rainbowadn/testing/failresolver.py index 6aed26f..9d9cf20 100644 --- a/rainbowadn/testing/failresolver.py +++ b/rainbowadn/testing/failresolver.py @@ -2,5 +2,5 @@ from rainbowadn.core.hashresolver import HashResolver class FailResolver(HashResolver): - def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: + async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: raise TypeError('fail-resolver always fails') diff --git a/rainbowadn/testing/instrumentation.py b/rainbowadn/testing/instrumentation.py index 419acba..2ba4b91 100644 --- a/rainbowadn/testing/instrumentation.py +++ b/rainbowadn/testing/instrumentation.py @@ -18,9 +18,13 @@ class Instrumentation: self.instrument(*args, **kwargs) return self.method(*args, **kwargs) - setattr(self.target, self.methodname, wrap) + self.wrap = wrap + + setattr(self.target, self.methodname, self.wrap) def __exit__(self, exc_type, exc_val, exc_tb): + assert getattr(self.target, self.methodname) is self.wrap + del self.wrap setattr(self.target, self.methodname, self.method) del self.method diff --git a/rainbowadn/testing/test_all.py b/rainbowadn/testing/test_all.py index 6e82f95..910212d 100644 --- a/rainbowadn/testing/test_all.py +++ b/rainbowadn/testing/test_all.py @@ -9,10 +9,10 @@ import nacl.signing from rainbowadn.chain.blockchain import BlockChainFactory from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface from rainbowadn.chain.reduction.reductionchainmetafactory import ReductionChainMetaFactory +from rainbowadn.core.asserts import assert_eq, assert_false, assert_true from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.nullability.notnull import NotNull from rainbowadn.core.rainbow_factory import RainbowFactory -from rainbowadn.core.resolvermetaorigin import ResolverMetaOrigin from rainbowadn.data.atomic.integer import Integer from rainbowadn.data.atomic.plain import Plain from rainbowadn.data.collection.pair import Pair, PairFactory @@ -32,14 +32,14 @@ from rainbowadn.wrisbt.wrisbtparametres import WrisbtParametres from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot -class TestAll(unittest.TestCase): +class TestAll(unittest.IsolatedAsyncioTestCase): """examples rather than real tests""" - def test_bankchain(self): + async def test_bankchain(self): with self.subTest('setup'): dr = DictResolver() with self.subTest('create empty'): - bank = BankChain.empty(ReductionChainMetaFactory()) + bank: BankChain = BankChain.empty(ReductionChainMetaFactory().loose()) with self.subTest('prepare transactions'): key_0 = nacl.signing.SigningKey.generate() transaction_0 = Transaction.make( @@ -47,9 +47,9 @@ class TestAll(unittest.TestCase): [CoinData.of(Subject(key_0.verify_key), 1_000_000)], [] ) - coin_0, coin_1 = transaction_0.coins(MINT_CONST, NotNull(HashPoint.of(Subject(key_0.verify_key)))) + coin_0, coin_1 = await transaction_0.coins(MINT_CONST, NotNull(HashPoint.of(Subject(key_0.verify_key)))) with self.subTest('add transactions'): - bank = bank.adds( + bank = await bank.adds( [ transaction_0, Transaction.make( @@ -60,22 +60,22 @@ class TestAll(unittest.TestCase): ] ) with self.subTest('add empty'): - bank = bank.adds( + bank = await bank.adds( [] ) print(bank) with self.subTest('verify'): - assert bank.verify() + assert_true(await bank.verify()) with self.subTest('recover'): - dr.save(HashPoint.of(bank.reference)) + await dr.save(HashPoint.of(bank.reference)) bank = BankChain.from_reference( - ReductionChainMetaFactory(), ResolverMetaOrigin(dr).migrate_resolved(bank.reference) + ReductionChainMetaFactory(), await dr.migrate_resolved(bank.reference) ) print(bank) with self.subTest('verify'): - assert bank.verify() + assert_true(await bank.verify()) - def test_wrisbt(self): + async def test_wrisbt(self): with self.subTest('setup'): stoptime = time.process_time() @@ -91,33 +91,33 @@ class TestAll(unittest.TestCase): n = 2500 keysize = 7 with self.subTest('create empty'): - btree = WrisbtRoot.empty(WrisbtParametres(1, keysize)) + btree: WrisbtRoot = WrisbtRoot.empty(WrisbtParametres(1, keysize)) measure('init') with self.subTest('add keys', n=n): for _ in range(n): key = os.urandom(keysize) - assert not btree.contains(key) - btree = btree.add(key) - assert btree.contains(key) + assert_false(await btree.contains(key)) + btree = await btree.add(key) + assert_true(await btree.contains(key)) measure('add') with self.subTest('save'): - dr.save(HashPoint.of(btree)) + await dr.save(HashPoint.of(btree)) measure('save') with self.subTest('resolve and iterate'): - btree = ResolverMetaOrigin(dr).migrate_resolved(btree) - assert len(btree.keys()) == n + btree = await dr.migrate_resolved(btree) + assert_eq(len(await btree.keys()), n) print(btree.height) measure('resolve and iterate') with self.subTest('resolve and add', n=n): for _ in range(n): key = os.urandom(keysize) - assert not btree.contains(key) - btree = btree.add(key) - assert btree.contains(key) + assert_false(await btree.contains(key)) + btree = await btree.add(key) + assert_true(await btree.contains(key)) print(btree.height) measure('resolve and add') - def test_wrisbt_index(self): + async def test_wrisbt_index(self): with self.subTest('create empty'): factory: RainbowFactory[Pair[Plain, Plain]] = PairFactory(Plain.factory(), Plain.factory()).loose() chain: ChainCollectionInterface[Any, Pair[Plain, Plain], WrisbtRoot] = BlockChainFactory( @@ -125,7 +125,7 @@ class TestAll(unittest.TestCase): ).empty().loose() with self.subTest('fill'): for _ in range(1000): - chain = chain.add( + chain = await chain.add( HashPoint.of( Pair( HashPoint.of(Plain(os.urandom(16))), @@ -134,29 +134,29 @@ class TestAll(unittest.TestCase): ) ) with self.subTest('check'): - assert chain + assert_true(await chain.verify()) with self.subTest('measure height'): - reference = chain.actual_state().reference + reference = await chain.actual_state() assert not reference.null() - print(reference.resolve().resolve().height) + print((await reference.resolve()).height) - def test_avl(self): + async def test_avl(self): tree: ActiveBinaryTree[Plain, Integer] = ActiveBinaryTree.empty( AVL(PlainComparator(Replace())), Plain.factory() ) for i in range(26): - tree = tree.add(HashPoint.of(Plain(bytes([ord('A') + i])))) - print(tree.reference.str(0)) + tree = await tree.add(HashPoint.of(Plain(bytes([ord('A') + i])))) + print(await tree.reference.str(0)) - def test_avl_stress(self): + async def test_avl_stress(self): tree: ActiveBinaryTree[Plain, Integer] = ActiveBinaryTree.empty( AVL(PlainComparator(Replace())), Plain.factory() ) for i in range(250): - tree = tree.add(HashPoint.of(Plain(os.urandom(16)))) - print(tree.loose().reference.resolve().key.resolve().metadata.resolve().integer) + tree = await tree.add(HashPoint.of(Plain(os.urandom(16)))) + print((await (await (await tree.loose().reference.resolve()).key.resolve()).metadata.resolve()).integer) - def test_encryption(self): + async def test_encryption(self): instrumentation = Counter(Encrypted, 'encrypt') with self.subTest('setup'): key = b'a' * 32 @@ -167,29 +167,29 @@ class TestAll(unittest.TestCase): ) with self.subTest('fill'): for char in string.ascii_uppercase: - tree = tree.add(HashPoint.of(Plain(char.encode()))) - print(tree.reference.str(0)) + tree = await tree.add(HashPoint.of(Plain(char.encode()))) + print(await tree.reference.str(0)) with self.subTest('encrypt'): target = tree.reference with instrumentation: - target = Encrypted.encrypt(target, key).decrypted + target = (await Encrypted.encrypt(target, key)).decrypted print(instrumentation.counter) tree = tree.create(target) - print(tree.reference.str(0)) + print(await tree.reference.str(0)) with self.subTest('alter'): - tree = tree.add(HashPoint.of(Plain(b'NEWKEY'))) - tree = tree.remove(HashPoint.of(Plain(b'F'))) - print(tree.reference.str(0)) + tree = await tree.add(HashPoint.of(Plain(b'NEWKEY'))) + tree = await tree.remove(HashPoint.of(Plain(b'F'))) + print(await tree.reference.str(0)) with self.subTest('encrypt and migrate'): target = tree.reference with instrumentation: - eeed = Encrypted.encrypt(target, key) + eeed = await Encrypted.encrypt(target, key) print(instrumentation.counter) - dr.save(HashPoint.of(eeed)) - print(ResolverMetaOrigin(dr).migrate_resolved(eeed).decrypted.str(0)) + await dr.save(HashPoint.of(eeed)) + print(await (await dr.migrate_resolved(eeed)).decrypted.str(0)) with self.subTest('re-encrypt'): new_key = b'b' * 32 target = eeed.decrypted with instrumentation: - Encrypted.encrypt(target, new_key) + await Encrypted.encrypt(target, new_key) print(instrumentation.counter) diff --git a/rainbowadn/toplevel/thresholdprotocol.py b/rainbowadn/toplevel/thresholdprotocol.py index 9de6a9b..e59eb22 100644 --- a/rainbowadn/toplevel/thresholdprotocol.py +++ b/rainbowadn/toplevel/thresholdprotocol.py @@ -6,5 +6,5 @@ Referenced = TypeVar('Referenced') class ThresholdProtocol(Generic[Referenced]): - def threshold(self, referenced: Referenced) -> bytes: + async def threshold(self, referenced: Referenced) -> bytes: raise NotImplementedError diff --git a/rainbowadn/toplevel/validreference.py b/rainbowadn/toplevel/validreference.py index a1b4f23..db3f89a 100644 --- a/rainbowadn/toplevel/validreference.py +++ b/rainbowadn/toplevel/validreference.py @@ -22,9 +22,9 @@ class ValidReference(RecursiveMentionable, Generic[Referenced]): def points(self) -> Iterable[HashPoint]: return [self.reference] - def resolve(self) -> Referenced: - referenced: Referenced = self.reference.resolve() - assert self.reference.point < self.protocol.threshold(referenced) + async def resolve(self) -> Referenced: + referenced: Referenced = await self.reference.resolve() + assert self.reference.point < (await self.protocol.threshold(referenced)) return referenced def __bytes__(self): diff --git a/rainbowadn/v13/bankchain.py b/rainbowadn/v13/bankchain.py index 86be024..128859a 100644 --- a/rainbowadn/v13/bankchain.py +++ b/rainbowadn/v13/bankchain.py @@ -62,23 +62,20 @@ class BankChain(Generic[BlockType]): ) ) - def add(self, stack: NullableReference[Stack[Transaction]]) -> 'BankChain[BlockType]': + async def add(self, stack: NullableReference[Stack[Transaction]]) -> 'BankChain[BlockType]': assert isinstance(stack, NullableReference) return BankChain( - self.chain.add(HashPoint.of(stack)) + await self.chain.add(HashPoint.of(stack)) ) - def adds(self, transactions: list[Transaction]) -> 'BankChain[BlockType]': + async def adds(self, transactions: list[Transaction]) -> 'BankChain[BlockType]': assert isinstance(transactions, list) - return self.add( + return await self.add( Stack.off( Transaction.factory(), reversed(transactions) ) ) - def verify(self) -> bool: - return self.chain.verify() - - def __str__(self): - return self.reference.str(0) + async def verify(self) -> bool: + return await self.chain.verify() diff --git a/rainbowadn/v13/bankprotocol.py b/rainbowadn/v13/bankprotocol.py index 5c52478..c34d341 100644 --- a/rainbowadn/v13/bankprotocol.py +++ b/rainbowadn/v13/bankprotocol.py @@ -19,22 +19,22 @@ __all__ = ('BankProtocol',) class BankProtocol(ReductionProtocol[NullableReference[Stack[Transaction]], BankState]): - def reduce( + async def reduce( self, reduction: Reduction[NullableReference[Stack[Transaction]], BankState] ) -> ReductionResult[NullableReference[Stack[Transaction]], BankState]: assert isinstance(reduction, Reduction) - bank_state: BankState = reduction.accumulator.resolve() + bank_state: BankState = await reduction.accumulator.resolve() assert isinstance(bank_state, BankState) - reference: NullableReference[Stack[Transaction]] = reduction.reductor.resolve() + reference: NullableReference[Stack[Transaction]] = await reduction.reductor.resolve() if reference.null(): return Reduced(HashPoint.of(bank_state.without_miner())) else: - stack: Stack[Transaction] = reference.resolve() + stack: Stack[Transaction] = await reference.resolve() assert isinstance(stack, Stack) return Reduction( HashPoint.of(stack.previous), - HashPoint.of(bank_state.push(stack.element)) + HashPoint.of(await bank_state.push(stack.element)) ) def initial(self, factory: RainbowFactory[BankState]) -> HashPoint[BankState]: @@ -54,6 +54,6 @@ class BankProtocol(ReductionProtocol[NullableReference[Stack[Transaction]], Bank ) ) - def header_filter(self, state: HashPoint[BankState]) -> HashPoint[BankState]: + async def header_filter(self, state: HashPoint[BankState]) -> HashPoint[BankState]: assert isinstance(state, HashPoint) - return HashPoint.of(state.resolve().without_miner().advance()) + return HashPoint.of(await (await state.resolve()).without_miner().advance()) diff --git a/rainbowadn/v13/bankstate.py b/rainbowadn/v13/bankstate.py index ed0a88c..50185a3 100644 --- a/rainbowadn/v13/bankstate.py +++ b/rainbowadn/v13/bankstate.py @@ -1,5 +1,6 @@ -from typing import Iterable +from typing import AsyncIterable, Iterable +from rainbowadn.core.asserts import assert_false, assert_true from rainbowadn.core.hash_point_format import hash_point_format, tabulate from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashresolver import HashResolver @@ -79,12 +80,12 @@ class BankState(RecursiveMentionable, StaticMentionable): self.length ) - def advance(self) -> 'BankState': + async def advance(self) -> 'BankState': return BankState( self.minted, self.used, NullableReference(Null(), self.miner.factory), - HashPoint.of(Integer(self.length.resolve().integer + 1)) + HashPoint.of(Integer((await self.length.resolve()).integer + 1)) ) def minted_tree(self) -> ActiveBinaryTree[Coin, Integer]: @@ -97,25 +98,25 @@ class BankState(RecursiveMentionable, StaticMentionable): AVL(HashComparator(Fail())), self.used ) - def use_coins(self, coins: Iterable[HashPoint[Coin]]) -> 'BankState': + async def use_coins(self, coins: AsyncIterable[HashPoint[Coin]]) -> 'BankState': minted: ActiveBinaryTree[Coin, Integer] = self.minted_tree() used: ActiveBinaryTree[Coin, Integer] = self.used_tree() - for in_coin in coins: - assert minted.contains(in_coin) - assert not used.contains(in_coin) - used = used.add(in_coin) + async for in_coin in coins: + assert_true(await minted.contains(in_coin)) + assert_false(await used.contains(in_coin)) + used = await used.add(in_coin) return BankState(self.minted, used.reference, self.miner, self.length) - def mint_coins( + async def mint_coins( self, transaction: Transaction ) -> 'BankState': - assert self.verify(transaction) + assert_true(await self.verify(transaction)) miner = self.miner_nullable() minted: ActiveBinaryTree[Coin, Integer] = self.minted_tree() - for coin, miner in transaction.iter_coins(self.mint(), miner): - assert not minted.contains(HashPoint.of(coin)) - minted = minted.add(HashPoint.of(coin)) + async for coin, miner in transaction.iter_coins(self.mint(), miner): + assert_false(await minted.contains(HashPoint.of(coin))) + minted = await minted.add(HashPoint.of(coin)) assert isinstance(minted, ActiveBinaryTree) return BankState(minted.reference, self.used, NullableReference(miner, self.miner.factory), self.length) @@ -128,32 +129,34 @@ class BankState(RecursiveMentionable, StaticMentionable): else: return 0 - def verify(self, transaction: Transaction) -> bool: + async def verify(self, transaction: Transaction) -> bool: assert isinstance(transaction, Transaction) - assert transaction.verify(self.mint()) + assert_true(await transaction.verify(self.mint())) return True - def _push(self, transaction: Transaction) -> 'BankState': + async def _push(self, transaction: Transaction) -> 'BankState': assert isinstance(transaction, Transaction) - return self.use_coins( - transaction.data_resolved().iter_in_coins() + return await ( + await self.use_coins( + (await transaction.data_resolved()).iter_in_coins() + ) ).mint_coins( transaction ) - def push(self, transaction: HashPoint[Transaction]) -> 'BankState': - return self._push(transaction.resolve()) + async def push(self, transaction: HashPoint[Transaction]) -> 'BankState': + return await self._push(await transaction.resolve()) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) return f'(' \ f'{tabulate(tab + 1)}bank' \ f'{tabulate(tab + 1)}(miner)' \ - f'{tabulate(tab + 1)}{self.miner.str(tab + 1)}' \ + f'{tabulate(tab + 1)}{await self.miner.str(tab + 1)}' \ f'{tabulate(tab + 1)}(minted)' \ - f'{tabulate(tab + 1)}{self.minted.str(tab + 1)}' \ + f'{tabulate(tab + 1)}{await self.minted.str(tab + 1)}' \ f'{tabulate(tab + 1)}(used)' \ - f'{tabulate(tab + 1)}{self.used.str(tab + 1)}' \ + f'{tabulate(tab + 1)}{await self.used.str(tab + 1)}' \ f'{tabulate(tab + 1)}(length)' \ - f'{tabulate(tab + 1)}{hash_point_format(self.length, tab + 1)}' \ + f'{tabulate(tab + 1)}{await hash_point_format(self.length, tab + 1)}' \ f'{tabulate(tab)})' diff --git a/rainbowadn/v13/signature.py b/rainbowadn/v13/signature.py index 264d99a..04f8fdb 100644 --- a/rainbowadn/v13/signature.py +++ b/rainbowadn/v13/signature.py @@ -2,6 +2,7 @@ import nacl.bindings import nacl.exceptions import nacl.signing +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.hashpoint import HashPoint from rainbowadn.data.atomic.atomic import Atomic from rainbowadn.v13.subject import Subject @@ -16,7 +17,7 @@ class BadSignature(nacl.exceptions.BadSignatureError): class Signature(Atomic): def __init__(self, source: bytes): assert isinstance(source, bytes) - assert len(source) == nacl.bindings.crypto_sign_BYTES + assert_eq(len(source), nacl.bindings.crypto_sign_BYTES) self.source = source @classmethod diff --git a/rainbowadn/v13/transaction.py b/rainbowadn/v13/transaction.py index 52ad86d..19f60ff 100644 --- a/rainbowadn/v13/transaction.py +++ b/rainbowadn/v13/transaction.py @@ -1,7 +1,8 @@ -from typing import Iterable +from typing import AsyncIterable, Iterable import nacl.signing +from rainbowadn.core.asserts import assert_true from rainbowadn.core.hash_point_format import hash_point_format, tabulate from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashresolver import HashResolver @@ -31,8 +32,8 @@ class CoinData(RecursiveMentionable, StaticMentionable): self.owner = owner self.value = value - def int_value(self) -> int: - return self.value.resolve().integer + async def int_value(self) -> int: + return (await self.value.resolve()).integer @classmethod def of(cls, owner: Subject, value: int) -> 'CoinData': @@ -55,10 +56,10 @@ class CoinData(RecursiveMentionable, StaticMentionable): ResolverOrigin(Integer.factory(), source[HashPoint.HASH_LENGTH:], resolver).hash_point(), ) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) - return f'{hash_point_format(self.owner, tab)}' \ - f'{tabulate(tab)}{hash_point_format(self.value, tab)}' + return f'{await hash_point_format(self.owner, tab)}' \ + f'{tabulate(tab)}{await hash_point_format(self.value, tab)}' class Coin(RecursiveMentionable, StaticMentionable): @@ -75,8 +76,8 @@ class Coin(RecursiveMentionable, StaticMentionable): self.origin = origin self.index = index - def data_resolved(self) -> CoinData: - return self.data.resolve() + async def data_resolved(self) -> CoinData: + return await self.data.resolve() def points(self) -> Iterable[HashPoint]: return [self.data, self.origin, self.index] @@ -96,13 +97,13 @@ class Coin(RecursiveMentionable, StaticMentionable): ResolverOrigin(Integer.factory(), source[2 * HashPoint.HASH_LENGTH:], resolver).hash_point(), ) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) return f'(' \ f'{tabulate(tab + 1)}coin' \ - f'{tabulate(tab + 1)}{hash_point_format(self.data, tab + 1)}' \ + f'{tabulate(tab + 1)}{await hash_point_format(self.data, tab + 1)}' \ f'{tabulate(tab + 1)}(origin)' \ - f'{tabulate(tab + 1)}{hash_point_format(self.index, tab + 1)}' \ + f'{tabulate(tab + 1)}{await hash_point_format(self.index, tab + 1)}' \ f'{tabulate(tab)})' @@ -138,59 +139,65 @@ class TransactionData(RecursiveMentionable, StaticMentionable): ).from_bytes(source[HashPoint.HASH_LENGTH:], resolver), ) - def _verify_signatures( + async def _verify_signatures( self, signatures: NullableReference[Stack[Signature]] ) -> bool: - for coin, signature in zip(self.iter_in_coins_resolved(), Stack.iter(signatures), strict=True): - assert signature.resolve().verify( - coin.data_resolved().owner.resolve(), - self.hash_point + for coin, signature in zip( + [x async for x in self.iter_in_coins_resolved()], + [x async for x in Stack.iter(signatures)], + strict=True + ): + assert_true( + (await signature.resolve()).verify( + await (await coin.data_resolved()).owner.resolve(), + self.hash_point + ) ) return True - def iter_in_coins(self) -> Iterable[HashPoint[Coin]]: + def iter_in_coins(self) -> AsyncIterable[HashPoint[Coin]]: return Stack.iter(self.in_coins) - def iter_in_coins_resolved(self) -> Iterable[Coin]: - for coin in Stack.iter(self.in_coins): - yield coin.resolve() + async def iter_in_coins_resolved(self) -> AsyncIterable[Coin]: + async for coin in self.iter_in_coins(): + yield await coin.resolve() - def _total_in(self) -> int: - return sum(coin.data_resolved().int_value() for coin in self.iter_in_coins_resolved()) + async def _total_in(self) -> int: + return sum([await (await coin.data_resolved()).int_value() async for coin in self.iter_in_coins_resolved()]) - def iter_out_coins(self) -> Iterable[HashPoint[CoinData]]: + def iter_out_coins(self) -> AsyncIterable[HashPoint[CoinData]]: return Stack.iter(self.out_coins) - def _total_out(self) -> int: - return sum(coin.resolve().int_value() for coin in self.iter_out_coins()) + async def _total_out(self) -> int: + return sum([await (await coin.resolve()).int_value() async for coin in self.iter_out_coins()]) - def _verify_values(self, mint: int) -> bool: + async def _verify_values(self, mint: int) -> bool: assert isinstance(mint, int) - assert self._total_out() <= self._total_in() + mint + assert (await self.extra(mint)) >= 0 return True - def extra(self, mint: int) -> int: + async def extra(self, mint: int) -> int: assert isinstance(mint, int) - return self._total_in() + mint - self._total_out() + return (await self._total_in()) + mint - (await self._total_out()) - def verify( + async def verify( self, signatures: NullableReference[Stack[Signature]], mint: int ) -> bool: assert isinstance(signatures, NullableReference) assert isinstance(mint, int) - assert self._verify_signatures(signatures) - assert self._verify_values(mint) + assert_true(await self._verify_signatures(signatures)) + assert_true(await self._verify_values(mint)) return True - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) return f'(in)' \ - f'{tabulate(tab)}{self.in_coins.str(tab)}' \ + f'{tabulate(tab)}{await self.in_coins.str(tab)}' \ f'{tabulate(tab)}(out)' \ - f'{tabulate(tab)}{self.out_coins.str(tab)}' + f'{tabulate(tab)}{await self.out_coins.str(tab)}' class Transaction(RecursiveMentionable, StaticMentionable): @@ -206,8 +213,8 @@ class Transaction(RecursiveMentionable, StaticMentionable): self.hash_point = HashPoint.of(self) assert isinstance(self.hash_point, HashPoint) - def data_resolved(self) -> TransactionData: - return self.data.resolve() + async def data_resolved(self) -> TransactionData: + return await self.data.resolve() def points(self) -> Iterable[HashPoint]: return [self.data, *self.signatures.points()] @@ -228,19 +235,19 @@ class Transaction(RecursiveMentionable, StaticMentionable): NullableReferenceFactory(stack_factory).from_bytes(source[HashPoint.HASH_LENGTH:], resolver), ) - def iter_coins( + async def iter_coins( self, mint: int, miner: Nullable[HashPoint[Subject]] - ) -> Iterable[tuple[Coin, Nullable[HashPoint[Subject]]]]: - transaction_data: TransactionData = self.data_resolved() + ) -> AsyncIterable[tuple[Coin, Nullable[HashPoint[Subject]]]]: + transaction_data: TransactionData = await self.data_resolved() assert isinstance(transaction_data, TransactionData) index = 0 out_coin: HashPoint[CoinData] - for out_coin in transaction_data.iter_out_coins(): + async for out_coin in transaction_data.iter_out_coins(): assert isinstance(out_coin, HashPoint) if miner.null(): - miner = NotNull(out_coin.resolve().owner) + miner = NotNull((await out_coin.resolve()).owner) assert isinstance(miner, Nullable) coin: Coin = Coin(out_coin, self.hash_point, HashPoint.of(Integer(index))) assert isinstance(coin, Coin) @@ -251,7 +258,7 @@ class Transaction(RecursiveMentionable, StaticMentionable): HashPoint.of( CoinData( miner.resolve(), - HashPoint.of(Integer(transaction_data.extra(mint))) + HashPoint.of(Integer(await transaction_data.extra(mint))) ) ), self.hash_point, @@ -260,23 +267,23 @@ class Transaction(RecursiveMentionable, StaticMentionable): assert isinstance(coin, Coin) yield coin, miner - def coins( + async def coins( self, mint: int, miner: Nullable[HashPoint[Subject]] ) -> list[Coin]: assert isinstance(mint, int) assert isinstance(miner, Nullable) - return [coin for coin, _ in self.iter_coins(mint, miner)] + return [coin async for coin, _ in self.iter_coins(mint, miner)] - def verify(self, mint: int): + async def verify(self, mint: int): assert isinstance(mint, int) - data: TransactionData = self.data_resolved() + data: TransactionData = await self.data_resolved() assert isinstance(data, TransactionData) - assert data.verify(self.signatures, mint) + assert_true(await data.verify(self.signatures, mint)) return True - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) return f'(' \ f'{tabulate(tab + 1)}transaction' \ diff --git a/rainbowadn/wrisbt/weakreferenceindexsetbtree.py b/rainbowadn/wrisbt/weakreferenceindexsetbtree.py index ab61478..e8fd73c 100644 --- a/rainbowadn/wrisbt/weakreferenceindexsetbtree.py +++ b/rainbowadn/wrisbt/weakreferenceindexsetbtree.py @@ -1,6 +1,7 @@ import bisect -from typing import Iterable, Sequence +from typing import AsyncIterable, Iterable, Sequence +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.hash_point_format import hash_point_format, tabulate from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashresolver import HashResolver @@ -47,7 +48,7 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): else: self.keys = self.length // (parametres.keysize + HashPoint.HASH_LENGTH) self.children = self.keys + 1 - assert self.length == self.keys * parametres.keysize + self.children * HashPoint.HASH_LENGTH + assert_eq(self.length, self.keys * parametres.keysize + self.children * HashPoint.HASH_LENGTH) self.parametres = parametres self.keymin = parametres.keymin @@ -60,7 +61,7 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): self.keyend = self.keys * self.keysize - assert len(cache) == self.children + assert_eq(len(cache), self.children) self.cache = cache def full(self) -> bool: @@ -95,11 +96,11 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): self.bytes_no(index, self.keyend, HashPoint.HASH_LENGTH) ) - def child_resolved_no(self, index: int) -> 'WeakReferenceIndexSetBTree': + async def child_resolved_no(self, index: int) -> 'WeakReferenceIndexSetBTree': assert isinstance(index, int) assert 0 <= index < self.children assert not self.leaf - return self.child_no(index).resolve() + return await self.child_no(index).resolve() def balanced(self) -> bool: return self.keys <= 2 * self.keymin @@ -157,7 +158,7 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): self.range(self.keymin + 1, 2 * self.keymin + 1), ) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) formatted = f'{self.height}' \ @@ -165,14 +166,14 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): for key_index in range(self.keys): formatted += f'{tabulate(tab + 1)}{self.key_no(key_index).hex()}' for child_index in range(self.children): - formatted += f'{tabulate(tab + 1)}{hash_point_format(self.child_no(child_index), tab + 1)}' + formatted += f'{tabulate(tab + 1)}{await hash_point_format(self.child_no(child_index), tab + 1)}' return f'{formatted}' \ f'{tabulate(tab)})' - def contains(self, key: bytes) -> bool: + async def contains(self, key: bytes) -> bool: assert isinstance(key, bytes) - assert len(key) == self.keysize + assert_eq(len(key), self.keysize) assert self.balanced() @@ -187,13 +188,13 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): assert key > self.key_no(index - 1) if self.leaf: return False - child: WeakReferenceIndexSetBTree = self.child_resolved_no(index) + child: WeakReferenceIndexSetBTree = await self.child_resolved_no(index) assert isinstance(child, WeakReferenceIndexSetBTree) - return child.contains(key) + return await child.contains(key) - def add(self, key: bytes) -> 'WeakReferenceIndexSetBTree': + async def add(self, key: bytes) -> 'WeakReferenceIndexSetBTree': assert isinstance(key, bytes) - assert len(key) == self.keysize + assert_eq(len(key), self.keysize) assert self.balanced() @@ -214,9 +215,9 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): self.root, () ) - child: WeakReferenceIndexSetBTree = self.child_resolved_no(index) + child: WeakReferenceIndexSetBTree = await self.child_resolved_no(index) assert isinstance(child, WeakReferenceIndexSetBTree) - child: WeakReferenceIndexSetBTree = child.add(key) + child: WeakReferenceIndexSetBTree = await child.add(key) assert isinstance(child, WeakReferenceIndexSetBTree) if child.full(): left, middle, right = child.split() @@ -269,7 +270,7 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): ) ) - def iter_keys(self) -> Iterable[bytes]: + async def iter_keys(self) -> AsyncIterable[bytes]: if self.leaf: for key_index in range(self.keys): yield self.key_no(key_index) @@ -279,7 +280,8 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): if mode: yield self.key_no(real_index) else: - yield from self.child_resolved_no(real_index).iter_keys() + async for key in (await self.child_resolved_no(real_index)).iter_keys(): + yield key class KeyView(Sequence[WeakReferenceIndexSetBTree]): diff --git a/rainbowadn/wrisbt/wrisbtchainprotocol.py b/rainbowadn/wrisbt/wrisbtchainprotocol.py index a5a63b7..b630b3c 100644 --- a/rainbowadn/wrisbt/wrisbtchainprotocol.py +++ b/rainbowadn/wrisbt/wrisbtchainprotocol.py @@ -40,6 +40,6 @@ class WrisbtChainProtocol( def actual_state_factory(self) -> RainbowFactory[WrisbtRoot]: return WrisbtRootFactory(WrisbtParametres(self.keymin, HashPoint.HASH_LENGTH)) - def actual_state(self, state: WrisbtIndex) -> HashPoint[WrisbtRoot]: + async def actual_state(self, state: WrisbtIndex) -> HashPoint[WrisbtRoot]: assert isinstance(state, WrisbtIndex) return state.total diff --git a/rainbowadn/wrisbt/wrisbtindex.py b/rainbowadn/wrisbt/wrisbtindex.py index 9890ae8..c8ad102 100644 --- a/rainbowadn/wrisbt/wrisbtindex.py +++ b/rainbowadn/wrisbt/wrisbtindex.py @@ -36,11 +36,11 @@ class WrisbtIndex(RecursiveMentionable): def __factory__(self) -> RainbowFactory['WrisbtIndex']: return WrisbtIndexFactory(self.keymin) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) return f'(index)' \ - f'{tabulate(tab)}{hash_point_format(self.total, tab)}' \ - f'{tabulate(tab)}{hash_point_format(self.delta, tab)}' + f'{tabulate(tab)}{await hash_point_format(self.total, tab)}' \ + f'{tabulate(tab)}{await hash_point_format(self.delta, tab)}' class WrisbtIndexFactory(RainbowFactory[WrisbtIndex]): diff --git a/rainbowadn/wrisbt/wrisbtprotocol.py b/rainbowadn/wrisbt/wrisbtprotocol.py index 542a8a1..5fb2b45 100644 --- a/rainbowadn/wrisbt/wrisbtprotocol.py +++ b/rainbowadn/wrisbt/wrisbtprotocol.py @@ -26,25 +26,25 @@ class WrisbtProtocol(MetaReductionStateProtocol[TargetType, WrisbtIndex]): ) ) - def _derive( + async def _derive( self, previous: HashPoint[WrisbtIndex], header: HashPoint[TargetType] ) -> HashPoint[WrisbtIndex]: assert isinstance(previous, HashPoint) assert isinstance(header, HashPoint) - index: WrisbtIndex = previous.resolve() + index: WrisbtIndex = await previous.resolve() assert isinstance(index, WrisbtIndex) empty: WrisbtRoot = WrisbtRoot.empty(WrisbtParametres(self.keymin, HashPoint.HASH_LENGTH)) assert isinstance(empty, WrisbtRoot) - total: WrisbtRoot = index.total.resolve() + total: WrisbtRoot = await index.total.resolve() assert isinstance(total, WrisbtRoot) return HashPoint.of( WrisbtIndex( - HashPoint.of(total.index(header, empty)), - HashPoint.of(empty.index(header, total)), + HashPoint.of(await total.index(header, empty)), + HashPoint.of(await empty.index(header, total)), index.keymin ) ) diff --git a/rainbowadn/wrisbt/wrisbtroot.py b/rainbowadn/wrisbt/wrisbtroot.py index 76c474e..6242e87 100644 --- a/rainbowadn/wrisbt/wrisbtroot.py +++ b/rainbowadn/wrisbt/wrisbtroot.py @@ -1,5 +1,6 @@ from typing import Iterable +from rainbowadn.core.asserts import assert_eq from rainbowadn.core.hash_point_format import hash_point_format, tabulate from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashresolver import HashResolver @@ -25,8 +26,8 @@ class WrisbtRoot(RecursiveMentionable): self.height = height self.parametres = parametres - def root_resolved(self) -> 'WeakReferenceIndexSetBTree': - return self.root.resolve() + async def root_resolved(self) -> 'WeakReferenceIndexSetBTree': + return await self.root.resolve() def points(self) -> Iterable[HashPoint]: return [self.root] @@ -42,26 +43,26 @@ class WrisbtRoot(RecursiveMentionable): assert isinstance(parametres, WrisbtParametres) return WrisbtRoot(HashPoint.of(WeakReferenceIndexSetBTree(b'', 0, parametres, True, ())), 0, parametres) - def str(self, tab: int) -> str: + async def str(self, tab: int) -> str: assert isinstance(tab, int) return f'(root)' \ f'{tabulate(tab)}{self.height}' \ - f'{tabulate(tab)}{hash_point_format(self.root, tab)}' + f'{tabulate(tab)}{await hash_point_format(self.root, tab)}' - def contains(self, key: bytes) -> bool: + async def contains(self, key: bytes) -> bool: assert isinstance(key, bytes) - assert len(key) == self.parametres.keysize + assert_eq(len(key), self.parametres.keysize) - root: WeakReferenceIndexSetBTree = self.root_resolved() + root: WeakReferenceIndexSetBTree = await self.root_resolved() assert isinstance(root, WeakReferenceIndexSetBTree) - return root.contains(key) + return await root.contains(key) - def add(self, key: bytes) -> 'WrisbtRoot': + async def add(self, key: bytes) -> 'WrisbtRoot': assert isinstance(key, bytes) - assert len(key) == self.parametres.keysize + assert_eq(len(key), self.parametres.keysize) - root: WeakReferenceIndexSetBTree = self.root_resolved().add(key) + root: WeakReferenceIndexSetBTree = await (await self.root_resolved()).add(key) assert isinstance(root, WeakReferenceIndexSetBTree) if root.full(): @@ -84,25 +85,25 @@ class WrisbtRoot(RecursiveMentionable): assert isinstance(root, WeakReferenceIndexSetBTree) return cls(HashPoint.of(root), root.height, root.parametres) - def keys(self) -> list[bytes]: - return list(self.root_resolved().iter_keys()) + async def keys(self) -> list[bytes]: + return list([x async for x in (await self.root_resolved()).iter_keys()]) - def index( + async def index( self, target: HashPoint, exclude: 'WrisbtRoot' ) -> 'WrisbtRoot': assert isinstance(target, HashPoint) assert isinstance(exclude, WrisbtRoot) key: bytes = target.point assert isinstance(key, bytes) - if exclude.contains(key) or self.contains(key): + if await exclude.contains(key) or await self.contains(key): return self - tree = self - value: Mentionable = target.resolve() + tree: WrisbtRoot = self + value: Mentionable = await target.resolve() assert isinstance(value, Mentionable) if isinstance(value, RecursiveMentionable): for hash_point in value.points(): - tree = tree.index(hash_point, exclude) - tree = tree.add(key) + tree = await tree.index(hash_point, exclude) + tree = await tree.add(key) return tree