This commit is contained in:
AF 2022-06-19 22:53:02 +03:00
parent 69297cdac1
commit cf727d87b0
66 changed files with 595 additions and 475 deletions

View File

@ -40,15 +40,15 @@ class Block(RecursiveMentionable, Generic[HeaderType, StateType]):
self.state.factory, self.state.factory,
) )
def str(self, tab: int) -> str: async def str(self, tab: int) -> str:
assert isinstance(tab, int) assert isinstance(tab, int)
return f'{self.previous.str(tab)}' \ return f'{await self.previous.str(tab)}' \
f'{tabulate(tab)}(' \ f'{tabulate(tab)}(' \
f'{tabulate(tab + 1)}block' \ f'{tabulate(tab + 1)}block' \
f'{tabulate(tab + 1)}(header)' \ 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)}(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)})' f'{tabulate(tab)})'

View File

@ -1,9 +1,11 @@
import asyncio
from typing import Generic, TypeVar from typing import Generic, TypeVar
from rainbowadn.chain.block import Block, BlockFactory from rainbowadn.chain.block import Block, BlockFactory
from rainbowadn.chain.blockchainprotocol import BlockChainProtocol from rainbowadn.chain.blockchainprotocol import BlockChainProtocol
from rainbowadn.chain.chaincollectionfactory import ChainCollectionFactory from rainbowadn.chain.chaincollectionfactory import ChainCollectionFactory
from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface
from rainbowadn.core.asserts import assert_eq, assert_true
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.nullability.null import Null from rainbowadn.core.nullability.null import Null
from rainbowadn.core.nullability.nullablereference import NullableReference from rainbowadn.core.nullability.nullablereference import NullableReference
@ -52,7 +54,7 @@ class BlockChain(
]: ]:
return BlockChainFactory(self.protocol) return BlockChainFactory(self.protocol)
def add( async def add(
self, self,
header: HashPoint[HeaderType] header: HashPoint[HeaderType]
) -> ChainCollectionInterface[ ) -> ChainCollectionInterface[
@ -66,11 +68,11 @@ class BlockChain(
assert isinstance(header, HashPoint) assert isinstance(header, HashPoint)
return self.factory().from_reference( return self.factory().from_reference(
NullableReference.off( NullableReference.off(
self._add(header) await self._add(header)
) )
) )
def state( async def state(
self self
) -> NullableReference[ ) -> NullableReference[
StateType StateType
@ -81,11 +83,11 @@ class BlockChain(
self.protocol.state_factory self.protocol.state_factory
) )
else: else:
block: Block[HeaderType, StateType] = self.reference.resolve() block: Block[HeaderType, StateType] = await self.reference.resolve()
assert isinstance(block, Block) assert isinstance(block, Block)
return NullableReference.of(block.state) return NullableReference.of(block.state)
def _add( async def _add(
self, self,
header: HashPoint[HeaderType] header: HashPoint[HeaderType]
) -> Block[ ) -> Block[
@ -96,13 +98,13 @@ class BlockChain(
return Block( return Block(
self.reference, self.reference,
header, header,
self.protocol.state_protocol.derive( await self.protocol.state_protocol.derive(
self.state(), await self.state(),
header, header,
) )
) )
def previous( async def previous(
self self
) -> ChainCollectionInterface[ ) -> ChainCollectionInterface[
Block[ Block[
@ -116,19 +118,22 @@ class BlockChain(
block: Block[ block: Block[
HeaderType, HeaderType,
StateType StateType
] = self.reference.resolve() ] = await self.reference.resolve()
assert isinstance(block, Block) assert isinstance(block, Block)
return self.factory().from_reference(block.previous) return self.factory().from_reference(block.previous)
def verify(self) -> bool: async def verify(self) -> bool:
if self.reference.null(): if self.reference.null():
return True return True
else: else:
assert self.verify_link(self.previous().reference) previous: ChainCollectionInterface[
assert self.previous().verify() 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 return True
def _verify_link( async def _verify_link(
self, self,
block: Block[ block: Block[
HeaderType, HeaderType,
@ -143,20 +148,22 @@ class BlockChain(
) -> bool: ) -> bool:
assert isinstance(block, Block) assert isinstance(block, Block)
assert isinstance(previous, NullableReference) assert isinstance(previous, NullableReference)
assert block.previous == previous assert_eq(block.previous, previous)
previous_chain = self.factory().from_reference(previous) previous_chain = self.factory().from_reference(previous)
assert isinstance(previous_chain, BlockChain) assert isinstance(previous_chain, BlockChain)
assert self.protocol.state_protocol.verify( assert_true(
previous_chain.state(), await self.protocol.state_protocol.verify(
await previous_chain.state(),
block.header, block.header,
block.state, block.state,
) )
)
return True return True
def _actual_state_factory(self) -> RainbowFactory[ActualStateType]: def _actual_state_factory(self) -> RainbowFactory[ActualStateType]:
return self.protocol.actual_state_factory() return self.protocol.actual_state_factory()
def _actual_state( async def _actual_state(
self, self,
block: Block[ block: Block[
HeaderType, HeaderType,
@ -164,7 +171,7 @@ class BlockChain(
] ]
) -> HashPoint[ActualStateType]: ) -> HashPoint[ActualStateType]:
assert isinstance(block, Block) 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[ def loose(self) -> ChainCollectionInterface[
Block[ Block[

View File

@ -30,7 +30,7 @@ class BlockChainProtocol(
def actual_state_factory(self) -> RainbowFactory[ActualStateType]: def actual_state_factory(self) -> RainbowFactory[ActualStateType]:
raise NotImplementedError raise NotImplementedError
def actual_state( async def actual_state(
self, self,
state: StateType state: StateType
) -> HashPoint[ActualStateType]: ) -> HashPoint[ActualStateType]:

View File

@ -26,14 +26,14 @@ class BlockCollectionInterface(
assert isinstance(reference, NullableReference) assert isinstance(reference, NullableReference)
super().__init__(reference) super().__init__(reference)
def _verify_link( async def _verify_link(
self, self,
block: BlockType, block: BlockType,
previous: NullableReference[BlockType] previous: NullableReference[BlockType]
) -> bool: ) -> bool:
raise NotImplementedError raise NotImplementedError
def verify_link( async def verify_link(
self, self,
previous: NullableReference[BlockType] previous: NullableReference[BlockType]
) -> bool: ) -> bool:
@ -41,24 +41,24 @@ class BlockCollectionInterface(
if self.reference.null(): if self.reference.null():
return True return True
else: else:
return self._verify_link( return await self._verify_link(
self.reference.resolve(), await self.reference.resolve(),
previous previous
) )
def _actual_state_factory(self) -> RainbowFactory[ActualStateType]: def _actual_state_factory(self) -> RainbowFactory[ActualStateType]:
raise NotImplementedError raise NotImplementedError
def _actual_state(self, block: BlockType) -> HashPoint[ActualStateType]: async def _actual_state(self, block: BlockType) -> HashPoint[ActualStateType]:
raise NotImplementedError raise NotImplementedError
def actual_state(self) -> NullableReference[ActualStateType]: async def actual_state(self) -> NullableReference[ActualStateType]:
if self.reference.null(): if self.reference.null():
return NullableReference(Null(), self._actual_state_factory()) return NullableReference(Null(), self._actual_state_factory())
else: 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, self,
header: HashPoint[HeaderType] header: HashPoint[HeaderType]
) -> 'BlockCollectionInterface[BlockType, HeaderType, ActualStateType]': ) -> 'BlockCollectionInterface[BlockType, HeaderType, ActualStateType]':

View File

@ -20,8 +20,11 @@ class ChainCollectionInterface(
Generic[BlockType, HeaderType, ActualStateType], Generic[BlockType, HeaderType, ActualStateType],
abc.ABC 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 raise NotImplementedError
def verify(self) -> bool: async def verify(self) -> bool:
raise NotImplementedError raise NotImplementedError

View File

@ -34,10 +34,10 @@ class Reduction(
def __factory__(self) -> RainbowFactory['Reduction[ReductorType, AccumulatorType]']: def __factory__(self) -> RainbowFactory['Reduction[ReductorType, AccumulatorType]']:
return ReductionFactory(self.reductor.factory, self.accumulator.factory) 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) assert isinstance(tab, int)
return f'(reduction)' \ return f'(reduction)' \
f'{tabulate(tab)}{hash_point_format(self.accumulator, tab)}' f'{tabulate(tab)}{await hash_point_format(self.accumulator, tab)}'
class ReductionFactory( class ReductionFactory(

View File

@ -50,3 +50,13 @@ class ReductionChainMetaFactory(
accumulator_factory, accumulator_factory,
) )
) )
def loose(self) -> AbstractReductionChainMetaFactory[
Block[
ReductorType,
StateStage[ReductorType, AccumulatorType, Reduction[ReductorType, AccumulatorType]]
],
ReductorType,
AccumulatorType
]:
return self

View File

@ -66,7 +66,7 @@ class ReductionChainProtocol(
def actual_state_factory(self) -> RainbowFactory[AccumulatorType]: def actual_state_factory(self) -> RainbowFactory[AccumulatorType]:
return self.accumulator_factory return self.accumulator_factory
def actual_state( async def actual_state(
self, self,
state: StateStage[ state: StateStage[
ReductorType, ReductorType,

View File

@ -12,7 +12,7 @@ AccumulatorType = TypeVar('AccumulatorType')
class ReductionProtocol(Generic[ReductorType, AccumulatorType]): class ReductionProtocol(Generic[ReductorType, AccumulatorType]):
def reduce( async def reduce(
self, self,
reduction: Reduction[ReductorType, AccumulatorType] reduction: Reduction[ReductorType, AccumulatorType]
) -> ReductionResult[ReductorType, AccumulatorType]: ) -> ReductionResult[ReductorType, AccumulatorType]:
@ -21,7 +21,7 @@ class ReductionProtocol(Generic[ReductorType, AccumulatorType]):
def initial(self, factory: RainbowFactory[AccumulatorType]) -> HashPoint[AccumulatorType]: def initial(self, factory: RainbowFactory[AccumulatorType]) -> HashPoint[AccumulatorType]:
raise NotImplementedError raise NotImplementedError
def header_filter( async def header_filter(
self, self,
state: HashPoint[AccumulatorType] state: HashPoint[AccumulatorType]
) -> HashPoint[AccumulatorType]: ) -> HashPoint[AccumulatorType]:

View File

@ -26,7 +26,7 @@ class ReductionStageProtocol(
self.protocol = protocol self.protocol = protocol
super().__init__() super().__init__()
def _derive_accumulator( async def _derive_accumulator(
self, self,
previous: NullableReference[AccumulatorType], previous: NullableReference[AccumulatorType],
) -> HashPoint[AccumulatorType]: ) -> HashPoint[AccumulatorType]:
@ -34,9 +34,9 @@ class ReductionStageProtocol(
if previous.null(): if previous.null():
return self.protocol.initial(previous.factory) return self.protocol.initial(previous.factory)
else: else:
return self.protocol.header_filter(previous.hashpoint()) return await self.protocol.header_filter(previous.hashpoint())
def derive_header( async def derive_header(
self, self,
previous: NullableReference[AccumulatorType], previous: NullableReference[AccumulatorType],
header: HashPoint[ReductorType] header: HashPoint[ReductorType]
@ -46,7 +46,7 @@ class ReductionStageProtocol(
return HashPoint.of( return HashPoint.of(
Reduction( Reduction(
header, header,
self._derive_accumulator(previous) await self._derive_accumulator(previous)
) )
) )
@ -63,9 +63,9 @@ class ReductionStageProtocol(
else: else:
raise TypeError raise TypeError
def derive_stage_or_state( async def derive_stage_or_state(
self, self,
stage: HashPoint[Reduction[ReductorType, AccumulatorType]] stage: HashPoint[Reduction[ReductorType, AccumulatorType]]
) -> Derived[ReductorType, Reduction[ReductorType, AccumulatorType]]: ) -> Derived[ReductorType, Reduction[ReductorType, AccumulatorType]]:
assert isinstance(stage, HashPoint) 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()))

View File

@ -5,6 +5,7 @@ from rainbowadn.chain.stages.derivation.derivedstage import DerivedStage
from rainbowadn.chain.stages.derivation.derivedstate import DerivedState from rainbowadn.chain.stages.derivation.derivedstate import DerivedState
from rainbowadn.chain.stages.stage import StageStage, StageStageFactory, StateStage from rainbowadn.chain.stages.stage import StageStage, StageStageFactory, StateStage
from rainbowadn.chain.stages.stageprotocol import StageProtocol from rainbowadn.chain.stages.stageprotocol import StageProtocol
from rainbowadn.core.asserts import assert_eq
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.nullability.null import Null from rainbowadn.core.nullability.null import Null
from rainbowadn.core.nullability.nullablereference import NullableReference from rainbowadn.core.nullability.nullablereference import NullableReference
@ -21,21 +22,21 @@ class ActiveStageProtocol(
StageProtocol[HeaderType, BaseStateType, StageType], StageProtocol[HeaderType, BaseStateType, StageType],
Generic[HeaderType, BaseStateType, StageType] Generic[HeaderType, BaseStateType, StageType]
): ):
def derive_header( async def derive_header(
self, self,
previous: NullableReference[BaseStateType], previous: NullableReference[BaseStateType],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
) -> HashPoint[StageType]: ) -> HashPoint[StageType]:
raise NotImplementedError raise NotImplementedError
def derive_stage_or_state( async def derive_stage_or_state(
self, self,
stage: HashPoint[StageType], stage: HashPoint[StageType],
) -> Derived[BaseStateType, StageType]: ) -> Derived[BaseStateType, StageType]:
raise NotImplementedError raise NotImplementedError
@classmethod @classmethod
def _previous_base_state( async def _previous_base_state(
cls, cls,
previous_reference: NullableReference[StateStage[HeaderType, BaseStateType, StageType]], previous_reference: NullableReference[StateStage[HeaderType, BaseStateType, StageType]],
base_state_factory: RainbowFactory[BaseStateType], base_state_factory: RainbowFactory[BaseStateType],
@ -45,11 +46,11 @@ class ActiveStageProtocol(
if previous_reference.null(): if previous_reference.null():
return NullableReference(Null(), base_state_factory) return NullableReference(Null(), base_state_factory)
else: 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) assert isinstance(previous_state_stage, StateStage)
return NullableReference.of(previous_state_stage.state) return NullableReference.of(previous_state_stage.state)
def _derive_cycle( async def _derive_cycle(
self, self,
stage: StageStage[HeaderType, BaseStateType, StageType], stage: StageStage[HeaderType, BaseStateType, StageType],
stage_factory: RainbowFactory[StageType] stage_factory: RainbowFactory[StageType]
@ -57,7 +58,7 @@ class ActiveStageProtocol(
assert isinstance(stage, StageStage) assert isinstance(stage, StageStage)
assert isinstance(stage_factory, RainbowFactory) assert isinstance(stage_factory, RainbowFactory)
while True: 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) assert isinstance(derived, Derived)
if isinstance(derived, DerivedStage): if isinstance(derived, DerivedStage):
stage = StageStage(self, NullableReference.off(stage), derived.stage) stage = StageStage(self, NullableReference.off(stage), derived.stage)
@ -67,7 +68,7 @@ class ActiveStageProtocol(
else: else:
raise TypeError raise TypeError
def _derive_initial_stage( async def _derive_initial_stage(
self, self,
previous: NullableReference[BaseStateType], previous: NullableReference[BaseStateType],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
@ -85,10 +86,10 @@ class ActiveStageProtocol(
stage_factory stage_factory
) )
), ),
self.derive_header(previous, header) await self.derive_header(previous, header)
) )
def derive_full( async def derive_full(
self, self,
previous_reference: NullableReference[StateStage[HeaderType, BaseStateType, StageType]], previous_reference: NullableReference[StateStage[HeaderType, BaseStateType, StageType]],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
@ -99,9 +100,9 @@ class ActiveStageProtocol(
assert isinstance(header, HashPoint) assert isinstance(header, HashPoint)
assert isinstance(base_state_factory, RainbowFactory) assert isinstance(base_state_factory, RainbowFactory)
assert isinstance(stage_factory, RainbowFactory) assert isinstance(stage_factory, RainbowFactory)
return self._derive_cycle( return await self._derive_cycle(
self._derive_initial_stage( await self._derive_initial_stage(
self._previous_base_state( await self._previous_base_state(
previous_reference, previous_reference,
base_state_factory base_state_factory
), ),
@ -111,7 +112,7 @@ class ActiveStageProtocol(
stage_factory stage_factory
) )
def verify_header( async def verify_header(
self, self,
previous: NullableReference[BaseStateType], previous: NullableReference[BaseStateType],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
@ -120,35 +121,35 @@ class ActiveStageProtocol(
assert isinstance(previous, NullableReference) assert isinstance(previous, NullableReference)
assert isinstance(header, HashPoint) assert isinstance(header, HashPoint)
assert isinstance(stage, HashPoint) assert isinstance(stage, HashPoint)
assert stage == self.derive_header(previous, header) assert_eq(stage, await self.derive_header(previous, header))
return True return True
def verify_stage( async def verify_stage(
self, self,
previous: HashPoint[StageType], previous: HashPoint[StageType],
stage: HashPoint[StageType] stage: HashPoint[StageType]
) -> bool: ) -> bool:
assert isinstance(previous, HashPoint) assert isinstance(previous, HashPoint)
assert isinstance(stage, 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) assert isinstance(derived, Derived)
if isinstance(derived, DerivedStage): if isinstance(derived, DerivedStage):
assert stage == derived.stage assert_eq(stage, derived.stage)
return True return True
else: else:
raise TypeError raise TypeError
def verify_state( async def verify_state(
self, self,
stage: HashPoint[StageType], stage: HashPoint[StageType],
state: HashPoint[BaseStateType] state: HashPoint[BaseStateType]
) -> bool: ) -> bool:
assert isinstance(stage, HashPoint) assert isinstance(stage, HashPoint)
assert isinstance(state, 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) assert isinstance(derived, Derived)
if isinstance(derived, DerivedState): if isinstance(derived, DerivedState):
assert state == derived.state assert_eq(state, derived.state)
return True return True
else: else:
raise TypeError raise TypeError

View File

@ -37,7 +37,7 @@ class ActiveStageStateProtocol(
self.stage_factory = stage_factory self.stage_factory = stage_factory
self.base_state_factory = base_state_factory self.base_state_factory = base_state_factory
def derive( async def derive(
self, self,
previous: NullableReference[ previous: NullableReference[
StateStage[ StateStage[
@ -56,7 +56,7 @@ class ActiveStageStateProtocol(
]: ]:
assert isinstance(previous, NullableReference) assert isinstance(previous, NullableReference)
assert isinstance(header, HashPoint) assert isinstance(header, HashPoint)
return self.protocol.derive_full( return await self.protocol.derive_full(
previous, previous,
header, header,
self.base_state_factory, self.base_state_factory,

View File

@ -1,6 +1,7 @@
from typing import Generic, Iterable, TypeVar from typing import Generic, Iterable, TypeVar
from rainbowadn.chain.stages.stageprotocol import StageProtocol 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.hash_point_format import hash_point_format, tabulate
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.hashresolver import HashResolver
@ -47,7 +48,7 @@ class StageStage(
self.stage = stage self.stage = stage
@classmethod @classmethod
def _previous_state( async def _previous_state(
cls, cls,
previous: NullableReference['StateStage[HeaderType, BaseStateType, StageType]'], previous: NullableReference['StateStage[HeaderType, BaseStateType, StageType]'],
base_factory: RainbowFactory[BaseStateType], base_factory: RainbowFactory[BaseStateType],
@ -57,11 +58,11 @@ class StageStage(
if previous.null(): if previous.null():
return NullableReference(Null(), base_factory) return NullableReference(Null(), base_factory)
else: else:
state_stage: StateStage[HeaderType, BaseStateType, StageType] = previous.resolve() state_stage: StateStage[HeaderType, BaseStateType, StageType] = await previous.resolve()
assert isinstance(state_stage, StateStage) assert isinstance(state_stage, StateStage)
return NullableReference.of(state_stage.state) return NullableReference.of(state_stage.state)
def verify( async def verify(
self, self,
previous: NullableReference['StateStage[HeaderType, BaseStateType, StageType]'], previous: NullableReference['StateStage[HeaderType, BaseStateType, StageType]'],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
@ -71,22 +72,28 @@ class StageStage(
assert isinstance(header, HashPoint) assert isinstance(header, HashPoint)
assert isinstance(base_factory, RainbowFactory) assert isinstance(base_factory, RainbowFactory)
if self.previous.null(): if self.previous.null():
return self.protocol.verify_header( return await self.protocol.verify_header(
self._previous_state(previous, base_factory), await self._previous_state(previous, base_factory),
header, header,
self.stage self.stage
) )
else: 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) assert isinstance(previous_stage, StageStage)
return self.protocol.verify_stage( assert_true(
await self.protocol.verify_stage(
previous_stage.stage, previous_stage.stage,
self.stage self.stage
) and previous_stage.verify( )
)
assert_true(
await previous_stage.verify(
previous, previous,
header, header,
base_factory base_factory
) )
)
return True
def points(self) -> Iterable[HashPoint]: def points(self) -> Iterable[HashPoint]:
return [*self.previous.points(), self.stage] return [*self.previous.points(), self.stage]
@ -100,10 +107,10 @@ class StageStage(
self.stage.factory self.stage.factory
) )
def str(self, tab: int) -> str: async def str(self, tab: int) -> str:
assert isinstance(tab, int) assert isinstance(tab, int)
return f'{self.previous.str(tab)}' \ return f'{await self.previous.str(tab)}' \
f'{tabulate(tab)}{hash_point_format(self.stage, tab)}' f'{tabulate(tab)}{await hash_point_format(self.stage, tab)}'
class StageStageFactory(RainbowFactory[StageStage[HeaderType, BaseStateType, StageType]]): class StageStageFactory(RainbowFactory[StageStage[HeaderType, BaseStateType, StageType]]):
@ -148,23 +155,29 @@ class StateStage(
self.state = state self.state = state
self.stage_factory = stage_factory self.stage_factory = stage_factory
def verify( async def verify(
self, self,
previous: NullableReference['StateStage[HeaderType, BaseStateType, StageType]'], previous: NullableReference['StateStage[HeaderType, BaseStateType, StageType]'],
header: HashPoint[HeaderType] header: HashPoint[HeaderType]
) -> bool: ) -> bool:
assert isinstance(previous, NullableReference) assert isinstance(previous, NullableReference)
assert isinstance(header, HashPoint) 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) assert isinstance(previous_stage, StageStage)
return self.protocol.verify_state( assert_true(
await self.protocol.verify_state(
previous_stage.stage, previous_stage.stage,
self.state self.state
) and previous_stage.verify( )
)
assert_true(
await previous_stage.verify(
previous, previous,
header, header,
self.state.factory self.state.factory
) )
)
return True
def points(self) -> Iterable[HashPoint]: def points(self) -> Iterable[HashPoint]:
return [self.previous, self.state] return [self.previous, self.state]
@ -179,10 +192,10 @@ class StateStage(
self.state.factory self.state.factory
) )
def str(self, tab: int) -> str: async def str(self, tab: int) -> str:
assert isinstance(tab, int) assert isinstance(tab, int)
return f'{hash_point_format(self.previous, tab)}' \ return f'{await hash_point_format(self.previous, tab)}' \
f'{tabulate(tab)}{hash_point_format(self.state, tab)}' f'{tabulate(tab)}{await hash_point_format(self.state, tab)}'
class StateStageFactory(RainbowFactory[StateStage[HeaderType, BaseStateType, StageType]]): class StateStageFactory(RainbowFactory[StateStage[HeaderType, BaseStateType, StageType]]):

View File

@ -11,7 +11,7 @@ StageType = TypeVar('StageType')
class StageProtocol(Generic[HeaderType, BaseStateType, StageType]): class StageProtocol(Generic[HeaderType, BaseStateType, StageType]):
def verify_header( async def verify_header(
self, self,
previous: NullableReference[BaseStateType], previous: NullableReference[BaseStateType],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
@ -19,14 +19,14 @@ class StageProtocol(Generic[HeaderType, BaseStateType, StageType]):
) -> bool: ) -> bool:
raise NotImplementedError raise NotImplementedError
def verify_stage( async def verify_stage(
self, self,
previous: HashPoint[StageType], previous: HashPoint[StageType],
stage: HashPoint[StageType] stage: HashPoint[StageType]
) -> bool: ) -> bool:
raise NotImplementedError raise NotImplementedError
def verify_state( async def verify_state(
self, self,
stage: HashPoint[StageType], stage: HashPoint[StageType],
state: HashPoint[BaseStateType] state: HashPoint[BaseStateType]

View File

@ -2,6 +2,7 @@ from typing import Generic, TypeVar
from rainbowadn.chain.stages.stage import StateStage from rainbowadn.chain.stages.stage import StateStage
from rainbowadn.chain.states.stateprotocol import StateProtocol from rainbowadn.chain.states.stateprotocol import StateProtocol
from rainbowadn.core.asserts import assert_true
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.nullability.nullablereference import NullableReference from rainbowadn.core.nullability.nullablereference import NullableReference
@ -16,7 +17,7 @@ class StageStateProtocol(
StateProtocol[HeaderType, StateStage[HeaderType, BaseStateType, StageType]], StateProtocol[HeaderType, StateStage[HeaderType, BaseStateType, StageType]],
Generic[HeaderType, BaseStateType, StageType] Generic[HeaderType, BaseStateType, StageType]
): ):
def verify( async def verify(
self, self,
previous: NullableReference[StateStage[HeaderType, BaseStateType, StageType]], previous: NullableReference[StateStage[HeaderType, BaseStateType, StageType]],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
@ -25,4 +26,5 @@ class StageStateProtocol(
assert isinstance(previous, NullableReference) assert isinstance(previous, NullableReference)
assert isinstance(header, HashPoint) assert isinstance(header, HashPoint)
assert isinstance(state, HashPoint) assert isinstance(state, HashPoint)
return state.resolve().verify(previous, header) assert_true(await (await state.resolve()).verify(previous, header))
return True

View File

@ -1,6 +1,7 @@
from typing import TypeVar from typing import TypeVar
from rainbowadn.chain.states.stateprotocol import StateProtocol from rainbowadn.chain.states.stateprotocol import StateProtocol
from rainbowadn.core.asserts import assert_eq
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.nullability.nullablereference import NullableReference from rainbowadn.core.nullability.nullablereference import NullableReference
@ -11,7 +12,7 @@ StateType = TypeVar('StateType')
class ActiveStateProtocol(StateProtocol[HeaderType, StateType]): class ActiveStateProtocol(StateProtocol[HeaderType, StateType]):
def verify( async def verify(
self, self,
previous: NullableReference[StateType], previous: NullableReference[StateType],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
@ -20,10 +21,10 @@ class ActiveStateProtocol(StateProtocol[HeaderType, StateType]):
assert isinstance(previous, NullableReference) assert isinstance(previous, NullableReference)
assert isinstance(header, HashPoint) assert isinstance(header, HashPoint)
assert isinstance(state, HashPoint) assert isinstance(state, HashPoint)
assert state == self.derive(previous, header) assert_eq(state, await self.derive(previous, header))
return True return True
def derive( async def derive(
self, self,
previous: NullableReference[StateType], previous: NullableReference[StateType],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],

View File

@ -1,6 +1,7 @@
from typing import TypeVar from typing import TypeVar
from rainbowadn.chain.states.activestateprotocol import ActiveStateProtocol from rainbowadn.chain.states.activestateprotocol import ActiveStateProtocol
from rainbowadn.core.asserts import assert_eq
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.nullability.nullablereference import NullableReference from rainbowadn.core.nullability.nullablereference import NullableReference
@ -11,7 +12,7 @@ StateType = TypeVar('StateType')
class MetaReductionStateProtocol(ActiveStateProtocol[HeaderType, StateType]): class MetaReductionStateProtocol(ActiveStateProtocol[HeaderType, StateType]):
def verify( async def verify(
self, self,
previous: NullableReference[StateType], previous: NullableReference[StateType],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
@ -20,20 +21,20 @@ class MetaReductionStateProtocol(ActiveStateProtocol[HeaderType, StateType]):
assert isinstance(previous, NullableReference) assert isinstance(previous, NullableReference)
assert isinstance(header, HashPoint) assert isinstance(header, HashPoint)
assert isinstance(state, HashPoint) assert isinstance(state, HashPoint)
assert state == self.derive(previous, header) assert_eq(state, await self.derive(previous, header))
return True return True
def _initial_state(self) -> HashPoint[StateType]: def _initial_state(self) -> HashPoint[StateType]:
raise NotImplementedError raise NotImplementedError
def _derive( async def _derive(
self, self,
previous: HashPoint[StateType], previous: HashPoint[StateType],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
) -> HashPoint[StateType]: ) -> HashPoint[StateType]:
raise NotImplementedError raise NotImplementedError
def derive( async def derive(
self, self,
previous: NullableReference[StateType], previous: NullableReference[StateType],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
@ -45,4 +46,4 @@ class MetaReductionStateProtocol(ActiveStateProtocol[HeaderType, StateType]):
else: else:
previous_state: HashPoint[StateType] = previous.hashpoint() previous_state: HashPoint[StateType] = previous.hashpoint()
assert isinstance(previous_state, HashPoint) assert isinstance(previous_state, HashPoint)
return self._derive(previous_state, header) return await self._derive(previous_state, header)

View File

@ -10,7 +10,7 @@ StateType = TypeVar('StateType')
class StateProtocol(Generic[HeaderType, StateType]): class StateProtocol(Generic[HeaderType, StateType]):
def verify( async def verify(
self, self,
previous: NullableReference[StateType], previous: NullableReference[StateType],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],

View File

@ -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

View File

@ -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()

View File

@ -1,15 +1,16 @@
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.mentionable import Mentionable
from rainbowadn.core.recursivementionable import RecursiveMentionable from rainbowadn.core.recursivementionable import RecursiveMentionable
__all__ = ('hash_point_format', 'tabulate',) __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(hash_point, HashPoint)
assert isinstance(tab, int) assert isinstance(tab, int)
value = hash_point.resolve() value: Mentionable = await hash_point.resolve()
if isinstance(value, RecursiveMentionable): if isinstance(value, RecursiveMentionable):
return value.str(tab) return await value.str(tab)
else: else:
return str(value) return str(value)

View File

@ -1,6 +1,7 @@
import hashlib import hashlib
from typing import Generic, TypeVar from typing import Generic, TypeVar
from rainbowadn.core.asserts import assert_eq
from rainbowadn.core.localorigin import LocalOrigin from rainbowadn.core.localorigin import LocalOrigin
from rainbowadn.core.mentionable import Mentionable from rainbowadn.core.mentionable import Mentionable
from rainbowadn.core.origin import Origin from rainbowadn.core.origin import Origin
@ -24,7 +25,7 @@ class HashPoint(Generic[Mentioned]):
): ):
assert isinstance(point, bytes) assert isinstance(point, bytes)
assert isinstance(origin, Origin) assert isinstance(origin, Origin)
assert len(point) == self.HASH_LENGTH assert_eq(len(point), self.HASH_LENGTH)
self.point = point self.point = point
self.origin = origin self.origin = origin
self.factory = origin.factory self.factory = origin.factory
@ -46,7 +47,7 @@ class HashPoint(Generic[Mentioned]):
assert isinstance(mentioned, Mentionable) assert isinstance(mentioned, Mentionable)
topology_hash: bytes = mentioned.__topology_hash__() topology_hash: bytes = mentioned.__topology_hash__()
assert isinstance(topology_hash, bytes) 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) return topology_hash + bytes(mentioned)
@classmethod @classmethod
@ -56,10 +57,10 @@ class HashPoint(Generic[Mentioned]):
cls.hash(cls.bytes_of_mentioned(mentioned)), LocalOrigin(mentioned) cls.hash(cls.bytes_of_mentioned(mentioned)), LocalOrigin(mentioned)
) )
def resolve(self) -> Mentioned: async def resolve(self) -> Mentioned:
resolved = self.origin.resolve() resolved: Mentioned = await self.origin.resolve()
assert isinstance(resolved, Mentionable) 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 return resolved
def __eq__(self, other): def __eq__(self, other):

View File

@ -2,5 +2,5 @@ __all__ = ('HashResolver',)
class HashResolver: class HashResolver:
def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
raise NotImplementedError raise NotImplementedError

View File

@ -1,5 +1,6 @@
from typing import Generic, TypeVar from typing import Generic, TypeVar
from rainbowadn.core.asserts import assert_eq
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.metaorigin import MetaOrigin from rainbowadn.core.metaorigin import MetaOrigin
from rainbowadn.core.origin import Origin 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]: def origin(self, factory: RainbowFactory[Mentioned], point: bytes) -> Origin[Mentioned]:
assert isinstance(factory, RainbowFactory) assert isinstance(factory, RainbowFactory)
assert isinstance(point, bytes) assert isinstance(point, bytes)
assert len(point) == HashPoint.HASH_LENGTH assert_eq(len(point), HashPoint.HASH_LENGTH)
return self._origin return self._origin

View File

@ -14,5 +14,5 @@ class LocalOrigin(Origin[Mentioned], Generic[Mentioned]):
super().__init__(value.__factory__()) super().__init__(value.__factory__())
self.value: Mentioned = value self.value: Mentioned = value
def resolve(self) -> Mentioned: async def resolve(self) -> Mentioned:
return self.value return self.value

View File

@ -1,5 +1,6 @@
from typing import Generic, TypeVar from typing import Generic, TypeVar
from rainbowadn.core.asserts import assert_eq
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.origin import Origin from rainbowadn.core.origin import Origin
from rainbowadn.core.rainbow_factory import RainbowFactory 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]: def hash_point(self, factory: RainbowFactory[Mentioned], point: bytes) -> HashPoint[Mentioned]:
assert isinstance(factory, RainbowFactory) assert isinstance(factory, RainbowFactory)
assert isinstance(point, bytes) assert isinstance(point, bytes)
assert len(point) == HashPoint.HASH_LENGTH assert_eq(len(point), HashPoint.HASH_LENGTH)
return HashPoint(point, self.origin(factory, point)) return HashPoint(point, self.origin(factory, point))

View File

@ -48,11 +48,11 @@ class NullableReference(RecursiveMentionable, Generic[Referenced]):
def off(cls, value: Referenced) -> 'NullableReference[Referenced]': def off(cls, value: Referenced) -> 'NullableReference[Referenced]':
return cls.of(HashPoint.of(value)) return cls.of(HashPoint.of(value))
def str(self, tab: int) -> str: async def str(self, tab: int) -> str:
if self.null(): if self.null():
return f'-' return f'-'
else: else:
return f'{hash_point_format(self.hashpoint(), tab)}' return f'{await hash_point_format(self.hashpoint(), tab)}'
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, NullableReference): if isinstance(other, NullableReference):
@ -67,9 +67,9 @@ class NullableReference(RecursiveMentionable, Generic[Referenced]):
assert not self.null() assert not self.null()
return self.reference.resolve() return self.reference.resolve()
def resolve(self) -> Referenced: async def resolve(self) -> Referenced:
assert not self.null() assert not self.null()
return self.hashpoint().resolve() return await self.hashpoint().resolve()
class NullableReferenceFactory(RainbowFactory[NullableReference[Referenced]], Generic[Referenced]): class NullableReferenceFactory(RainbowFactory[NullableReference[Referenced]], Generic[Referenced]):

View File

@ -11,5 +11,5 @@ class Origin(Generic[Mentioned]):
def __init__(self, factory: RainbowFactory[Mentioned]): def __init__(self, factory: RainbowFactory[Mentioned]):
self.factory = factory self.factory = factory
def resolve(self) -> Mentioned: async def resolve(self) -> Mentioned:
raise NotImplementedError raise NotImplementedError

View File

@ -11,7 +11,7 @@ class RecursiveMentionable(Mentionable, abc.ABC):
def points(self) -> Iterable[HashPoint]: def points(self) -> Iterable[HashPoint]:
raise NotImplementedError raise NotImplementedError
def str(self, tab: int) -> str: async def str(self, tab: int) -> str:
assert isinstance(tab, int) assert isinstance(tab, int)
return f'(recursive {self.__class__.__name__})' return f'(recursive {self.__class__.__name__})'

View File

@ -1,5 +1,6 @@
from typing import Generic, TypeVar from typing import Generic, TypeVar
from rainbowadn.core.asserts import assert_eq
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.hashresolver import HashResolver
from rainbowadn.core.metaorigin import MetaOrigin 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]: def origin(self, factory: RainbowFactory[Mentioned], point: bytes) -> Origin[Mentioned]:
assert isinstance(factory, RainbowFactory) assert isinstance(factory, RainbowFactory)
assert isinstance(point, bytes) assert isinstance(point, bytes)
assert len(point) == HashPoint.HASH_LENGTH assert_eq(len(point), HashPoint.HASH_LENGTH)
return ResolverOrigin(factory, point, self.resolver) 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()

View File

@ -1,5 +1,6 @@
from typing import Generic, TypeVar from typing import Generic, TypeVar
from rainbowadn.core.asserts import assert_eq
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.hashresolver import HashResolver
from rainbowadn.core.mentionable import Mentionable from rainbowadn.core.mentionable import Mentionable
@ -26,14 +27,14 @@ class ResolverOrigin(Origin[Mentioned], Generic[Mentioned]):
self.resolver = resolver self.resolver = resolver
super().__init__(factory) super().__init__(factory)
def resolve(self) -> Mentioned: async def resolve(self) -> Mentioned:
resolved, resolver = self.resolver.resolve(self.point) resolved, resolver = await self.resolver.resolve(self.point)
assert isinstance(resolved, bytes) assert isinstance(resolved, bytes)
assert isinstance(resolver, HashResolver) assert isinstance(resolver, HashResolver)
mentioned: Mentioned = self.factory.from_bytes(resolved[HashPoint.HASH_LENGTH:], resolver) mentioned: Mentioned = self.factory.from_bytes(resolved[HashPoint.HASH_LENGTH:], resolver)
assert isinstance(mentioned, Mentionable) assert isinstance(mentioned, Mentionable)
assert mentioned.__topology_hash__() == resolved[:HashPoint.HASH_LENGTH] assert_eq(mentioned.__topology_hash__(), resolved[:HashPoint.HASH_LENGTH])
assert self.point == HashPoint.hash(HashPoint.bytes_of_mentioned(mentioned)) assert_eq(self.point, HashPoint.hash(HashPoint.bytes_of_mentioned(mentioned)))
return mentioned return mentioned
def hash_point(self) -> HashPoint[Mentioned]: def hash_point(self) -> HashPoint[Mentioned]:

View File

@ -32,11 +32,11 @@ class Array(RecursiveMentionable, Generic[ElementType]):
def __factory__(self) -> RainbowFactory['Array']: def __factory__(self) -> RainbowFactory['Array']:
return ArrayFactory(self.factory) return ArrayFactory(self.factory)
def str(self, tab: int) -> str: async def str(self, tab: int) -> str:
assert isinstance(tab, int) assert isinstance(tab, int)
formatted = f'(' formatted = f'('
for hash_point in self.array: 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}' \ return f'{formatted}' \
f'{tabulate(tab)})' f'{tabulate(tab)})'

View File

@ -29,10 +29,10 @@ class KeyMetadata(Keyed[ActiveKeyType], Generic[ActiveKeyType, MetaDataType]):
def __factory__(self) -> RainbowFactory['KeyMetadata[ActiveKeyType, MetaDataType]']: def __factory__(self) -> RainbowFactory['KeyMetadata[ActiveKeyType, MetaDataType]']:
return KeyMetadataFactory(self.key.factory, self.metadata.factory) 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) assert isinstance(tab, int)
return f'{hash_point_format(self.key, tab)}' \ return f'{await hash_point_format(self.key, tab)}' \
f'{tabulate(tab)}{hash_point_format(self.metadata, tab)}' f'{tabulate(tab)}{await hash_point_format(self.metadata, tab)}'
class KeyMetadataFactory( class KeyMetadataFactory(

View File

@ -32,11 +32,11 @@ class Pair(
def __factory__(self) -> RainbowFactory['Pair[E0Type, E1Type]']: def __factory__(self) -> RainbowFactory['Pair[E0Type, E1Type]']:
return PairFactory(self.element0.factory, self.element1.factory) 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) assert isinstance(tab, int)
return f'(pair)' \ return f'(pair)' \
f'{tabulate(tab)}{hash_point_format(self.element0, tab)}' \ f'{tabulate(tab)}{await hash_point_format(self.element0, tab)}' \
f'{tabulate(tab)}{hash_point_format(self.element1, tab)}' f'{tabulate(tab)}{await hash_point_format(self.element1, tab)}'
class PairFactory( class PairFactory(

View File

@ -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.hash_point_format import hash_point_format, tabulate
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
@ -35,10 +35,10 @@ class Stack(RecursiveMentionable, Generic[ElementType]):
def __bytes__(self): def __bytes__(self):
return bytes(self.previous) + bytes(self.element) return bytes(self.previous) + bytes(self.element)
def str(self, tab: int) -> str: async def str(self, tab: int) -> str:
assert isinstance(tab, int) assert isinstance(tab, int)
return f'{self.previous.str(tab)}' \ return f'{await self.previous.str(tab)}' \
f'{tabulate(tab)}{hash_point_format(self.element, tab)}' f'{tabulate(tab)}{await hash_point_format(self.element, tab)}'
@classmethod @classmethod
def of( def of(
@ -69,17 +69,18 @@ class Stack(RecursiveMentionable, Generic[ElementType]):
return cls.of(factory, map(HashPoint.of, elements)) return cls.of(factory, map(HashPoint.of, elements))
@classmethod @classmethod
def iter( async def iter(
cls, cls,
reference: NullableReference['Stack[ElementType]'] reference: NullableReference['Stack[ElementType]']
) -> Iterable[HashPoint[ElementType]]: ) -> AsyncIterable[HashPoint[ElementType]]:
assert isinstance(reference, NullableReference) assert isinstance(reference, NullableReference)
if reference.null(): if reference.null():
pass pass
else: else:
stack: Stack[ElementType] = reference.resolve() stack: Stack[ElementType] = await reference.resolve()
yield stack.element 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]): class StackFactory(RainbowFactory[Stack[ElementType]], Generic[ElementType]):

View File

@ -12,31 +12,25 @@ ActionType = TypeVar('ActionType')
class BinaryTreeAction(Generic[ActiveKeyType, MetaDataType, TreeType, ActionType]): class BinaryTreeAction(Generic[ActiveKeyType, MetaDataType, TreeType, ActionType]):
def on( async def on(
self, self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType tree: TreeType
) -> ActionType: ) -> ActionType:
if (split := protocol.split(tree)) is None: if (split := await protocol.split(tree)) is None:
return self.on_null(protocol, tree) return await self.on_null(protocol, tree)
else: 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, self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType tree: TreeType
) -> ActionType: ) -> ActionType:
raise NotImplementedError raise NotImplementedError
def on_split( async def on_split(
self, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType]
) -> ActionType: ) -> ActionType:
raise NotImplementedError raise NotImplementedError
def per(
self: 'BinaryTreeAction[ActiveKeyType, MetaDataType, TreeType, ActionType]',
_protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType]
) -> 'BinaryTreeAction[ActiveKeyType, MetaDataType, TreeType, ActionType]':
return self

View File

@ -23,36 +23,36 @@ class CompareAction(
assert isinstance(key, HashPoint) assert isinstance(key, HashPoint)
self.key = key self.key = key
def on_split( async def on_split(
self, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType]
) -> ActionType: ) -> ActionType:
assert isinstance(case, BinaryTreeCase) 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) assert isinstance(comparison, Comparison)
if isinstance(comparison, Equal): if isinstance(comparison, Equal):
return self.on_equal(case, comparison) return await self.on_equal(case, comparison)
elif isinstance(comparison, Left): elif isinstance(comparison, Left):
return self.on_left(case) return await self.on_left(case)
elif isinstance(comparison, Right): elif isinstance(comparison, Right):
return self.on_right(case) return await self.on_right(case)
else: else:
raise TypeError raise TypeError
def on_equal( async def on_equal(
self, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType], case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType],
equal: Equal equal: Equal
) -> ActionType: ) -> ActionType:
raise NotImplementedError raise NotImplementedError
def on_left( async def on_left(
self, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType]
) -> ActionType: ) -> ActionType:
raise NotImplementedError raise NotImplementedError
def on_right( async def on_right(
self, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType]
) -> ActionType: ) -> ActionType:

View File

@ -22,34 +22,42 @@ class AddAction(
], ],
Generic[ActiveKeyType, MetaDataType, TreeType] Generic[ActiveKeyType, MetaDataType, TreeType]
): ):
def on_equal( async def on_equal(
self, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType], case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType],
equal: Equal equal: Equal
) -> TreeType: ) -> TreeType:
if isinstance(equal, Replace): 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: else:
raise TypeError raise TypeError
def on_left( async def on_left(
self, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType]
) -> 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, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType]
) -> 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, self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType tree: TreeType
) -> TreeType: ) -> TreeType:
return protocol.tree(tree, tree, self.key) return await protocol.tree(tree, tree, self.key)
class MergeAction( class MergeAction(
@ -64,22 +72,22 @@ class MergeAction(
def __init__(self, treer: TreeType): def __init__(self, treer: TreeType):
self.treer = treer self.treer = treer
def on_null( async def on_null(
self, self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType tree: TreeType
) -> TreeType: ) -> TreeType:
return self.treer return self.treer
def on_split( async def on_split(
self, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType]
) -> TreeType: ) -> TreeType:
protocol = case.protocol protocol = case.protocol
split = case.split split = case.split
return protocol.tree( return await protocol.tree(
split.treel, split.treel,
MergeAction(self.treer).on(protocol, split.treer), await MergeAction(self.treer).on(protocol, split.treer),
split.key split.key
) )
@ -93,26 +101,34 @@ class RemoveAction(
], ],
Generic[ActiveKeyType, MetaDataType, TreeType] Generic[ActiveKeyType, MetaDataType, TreeType]
): ):
def on_equal( async def on_equal(
self, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType], case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType],
equal: Equal equal: Equal
) -> TreeType: ) -> 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, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType]
) -> 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, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType]
) -> 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, self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType tree: TreeType
@ -129,26 +145,26 @@ class ContainsAction(
], ],
Generic[ActiveKeyType, MetaDataType, TreeType] Generic[ActiveKeyType, MetaDataType, TreeType]
): ):
def on_equal( async def on_equal(
self, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType], case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType],
equal: Equal equal: Equal
) -> bool: ) -> bool:
return True return True
def on_left( async def on_left(
self, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType]
) -> bool: ) -> 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, self,
case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType] case: BinaryTreeCase[ActiveKeyType, MetaDataType, TreeType]
) -> bool: ) -> 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, self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType tree: TreeType

View File

@ -34,7 +34,7 @@ class Symmetric(
) -> TreeType: ) -> TreeType:
raise NotImplementedError raise NotImplementedError
def tree( async def tree(
self, self,
inner: TreeType, inner: TreeType,
outer: TreeType, outer: TreeType,
@ -56,13 +56,13 @@ class InnerOuter(Symmetric):
) -> TreeType: ) -> TreeType:
return split.treer return split.treer
def tree( async def tree(
self, self,
inner: TreeType, inner: TreeType,
outer: TreeType, outer: TreeType,
key: HashPoint[ActiveKeyType] key: HashPoint[ActiveKeyType]
) -> TreeType: ) -> TreeType:
return self.case.protocol.tree(inner, outer, key) return await self.case.protocol.tree(inner, outer, key)
class OuterInner(Symmetric): class OuterInner(Symmetric):
@ -78,10 +78,10 @@ class OuterInner(Symmetric):
) -> TreeType: ) -> TreeType:
return split.treel return split.treel
def tree( async def tree(
self, self,
inner: TreeType, inner: TreeType,
outer: TreeType, outer: TreeType,
key: HashPoint[ActiveKeyType] key: HashPoint[ActiveKeyType]
) -> TreeType: ) -> TreeType:
return self.case.protocol.tree(outer, inner, key) return await self.case.protocol.tree(outer, inner, key)

View File

@ -65,17 +65,17 @@ class ActiveBinaryTree(
reference reference
) )
def add(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': async def add(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
assert isinstance(key, HashPoint) 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) 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) assert isinstance(key, HashPoint)
return ContainsAction(key).on(self.creation, self) return await ContainsAction(key).on(self.creation, self)
def loose(self) -> CollectionInterface[ def loose(self) -> CollectionInterface[
BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]
@ -90,7 +90,7 @@ class ActiveCreationProtocol(
ActiveBinaryTree[ActiveKeyType, MetaDataType] ActiveBinaryTree[ActiveKeyType, MetaDataType]
] ]
): ):
def split( async def split(
self, self,
tree: ActiveBinaryTree[ActiveKeyType, MetaDataType] tree: ActiveBinaryTree[ActiveKeyType, MetaDataType]
) -> Optional[ ) -> Optional[
@ -104,15 +104,15 @@ class ActiveCreationProtocol(
if tree.reference.null(): if tree.reference.null():
return None return None
else: else:
resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = tree.reference.resolve() resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = await tree.reference.resolve()
assert isinstance(resolved, BinaryTree) 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) assert isinstance(key_metadata, KeyMetadata)
return BinaryTreeSplit( return BinaryTreeSplit(
tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer) tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer)
) )
def _tree( async def _tree(
self, self,
treel: ActiveBinaryTree, treel: ActiveBinaryTree,
treer: ActiveBinaryTree, treer: ActiveBinaryTree,
@ -127,7 +127,7 @@ class ActiveCreationProtocol(
BinaryTree( BinaryTree(
treel.reference, treel.reference,
treer.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)))
) )
) )
) )

View File

@ -18,7 +18,7 @@ class AVL(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]):
def empty_metadata(self) -> HashPoint[Integer]: def empty_metadata(self) -> HashPoint[Integer]:
return HashPoint.of(Integer(0)) return HashPoint.of(Integer(0))
def metadata( async def metadata(
self, self,
treel: TreeType, treel: TreeType,
treer: TreeType, treer: TreeType,
@ -26,85 +26,90 @@ class AVL(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]):
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType] protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
) -> HashPoint[Integer]: ) -> HashPoint[Integer]:
return HashPoint.of( 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 @classmethod
def height( async def height(
cls, cls,
tree: TreeType, tree: TreeType,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType] protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
) -> int: ) -> int:
return HeightAction().on(protocol, tree) return await HeightAction().on(protocol, tree)
def balance( async def balance(
self, self,
tree: TreeType, tree: TreeType,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType] protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
) -> TreeType: ) -> TreeType:
return BalanceAction().on(protocol, tree) return await BalanceAction().on(protocol, tree)
class HeightAction( class HeightAction(
BinaryTreeAction[ActiveKeyType, Integer, TreeType, int], BinaryTreeAction[ActiveKeyType, Integer, TreeType, int],
Generic[ActiveKeyType, TreeType] Generic[ActiveKeyType, TreeType]
): ):
def on_null( async def on_null(
self, self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType], protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType],
tree: TreeType tree: TreeType
) -> int: ) -> int:
return 0 return 0
def on_split( async def on_split(
self, self,
case: BinaryTreeCase[ActiveKeyType, Integer, TreeType] case: BinaryTreeCase[ActiveKeyType, Integer, TreeType]
) -> int: ) -> int:
return case.split.metadata.resolve().integer metadata: Integer = await case.split.metadata.resolve()
return metadata.integer
class BalanceAction( class BalanceAction(
BinaryTreeAction[ActiveKeyType, Integer, TreeType, TreeType], BinaryTreeAction[ActiveKeyType, Integer, TreeType, TreeType],
Generic[ActiveKeyType, TreeType] Generic[ActiveKeyType, TreeType]
): ):
def on_null( async def on_null(
self, self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType], protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType],
tree: TreeType tree: TreeType
) -> TreeType: ) -> TreeType:
return tree return tree
def on_split( async def on_split(
self, self,
case: BinaryTreeCase[ActiveKeyType, Integer, TreeType] case: BinaryTreeCase[ActiveKeyType, Integer, TreeType]
) -> TreeType: ) -> TreeType:
split, protocol = case.split, case.protocol 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) assert isinstance(delta, int)
if delta < -1: if delta < -1:
return self.on_symmetric(InnerOuter(case)) return await self.on_symmetric(InnerOuter(case))
elif delta > 1: elif delta > 1:
return self.on_symmetric(OuterInner(case)) return await self.on_symmetric(OuterInner(case))
else: else:
return case.tree return case.tree
@classmethod @classmethod
def on_symmetric( async def on_symmetric(
cls, cls,
symmetric: Symmetric[ActiveKeyType, Integer, TreeType] symmetric: Symmetric[ActiveKeyType, Integer, TreeType]
) -> TreeType: ) -> TreeType:
protocol, split = symmetric.case.protocol, symmetric.case.split protocol, split = symmetric.case.protocol, symmetric.case.split
splito = protocol.fsplit(symmetric.outer(split)) splito = await protocol.fsplit(symmetric.outer(split))
if AVL.height(symmetric.inner(splito), protocol) > AVL.height(symmetric.outer(splito), protocol): if (
splitoi = protocol.fsplit(symmetric.inner(splito)) (await AVL.height(symmetric.inner(splito), protocol))
return symmetric.tree( >
symmetric.tree(symmetric.inner(split), symmetric.inner(splitoi), split.key), (await AVL.height(symmetric.outer(splito), protocol))
symmetric.tree(symmetric.outer(splitoi), symmetric.outer(splito), splito.key), ):
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 splitoi.key
) )
else: else:
return symmetric.tree( return await symmetric.tree(
symmetric.tree(symmetric.inner(split), symmetric.inner(splito), split.key), await symmetric.tree(symmetric.inner(split), symmetric.inner(splito), split.key),
symmetric.outer(splito), symmetric.outer(splito),
splito.key splito.key
) )

View File

@ -25,15 +25,15 @@ class BalancedTreeCreationProtocol(
self.protocol = protocol self.protocol = protocol
super().__init__(protocol.comparator) 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 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) assert isinstance(key, HashPoint)
return self.protocol.balance( return await self.protocol.balance(
self._tree( await self._tree(
self.protocol.balance(treel, self), await self.protocol.balance(treel, self),
self.protocol.balance(treer, self), await self.protocol.balance(treer, self),
key key
), ),
self self

View File

@ -40,11 +40,11 @@ class BinaryTree(RecursiveMentionable, Generic[TreeKeyType]):
def __bytes__(self): def __bytes__(self):
return bytes(self.treel) + bytes(self.treer) + bytes(self.key) 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) assert isinstance(tab, int)
return f'{self.treel.str(tab)}' \ return f'{await self.treel.str(tab)}' \
f'{tabulate(tab)}{hash_point_format(self.key, tab)}' \ f'{tabulate(tab)}{await hash_point_format(self.key, tab)}' \
f'{tabulate(tab)}{self.treer.str(tab)}' f'{tabulate(tab)}{await self.treer.str(tab)}'
class BinaryTreeFactory(RainbowFactory[BinaryTree[TreeKeyType]], Generic[TreeKeyType]): class BinaryTreeFactory(RainbowFactory[BinaryTree[TreeKeyType]], Generic[TreeKeyType]):

View File

@ -22,7 +22,7 @@ class BinaryTreeBalancingProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]
def empty_metadata(self) -> HashPoint[MetaDataType]: def empty_metadata(self) -> HashPoint[MetaDataType]:
raise NotImplementedError raise NotImplementedError
def metadata( async def metadata(
self, self,
treel: TreeType, treel: TreeType,
treer: TreeType, treer: TreeType,
@ -31,7 +31,7 @@ class BinaryTreeBalancingProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]
) -> HashPoint[MetaDataType]: ) -> HashPoint[MetaDataType]:
raise NotImplementedError raise NotImplementedError
def balance( async def balance(
self, self,
tree: TreeType, tree: TreeType,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType] protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType]

View File

@ -15,18 +15,18 @@ class BinaryTreeCreationProtocol(Generic[ActiveKeyType, MetaDataType, TreeType])
def __init__(self, comparator: Comparator[ActiveKeyType]): def __init__(self, comparator: Comparator[ActiveKeyType]):
self.comparator = comparator self.comparator = comparator
def split(self, tree: TreeType) -> Optional[ async def split(self, tree: TreeType) -> Optional[
BinaryTreeSplit[ActiveKeyType, MetaDataType, TreeType] BinaryTreeSplit[ActiveKeyType, MetaDataType, TreeType]
]: ]:
"""result of this method is supposed to be used right after the call, therefore all values are resolved""" """result of this method is supposed to be used right after the call, therefore all values are resolved"""
raise NotImplementedError raise NotImplementedError
def fsplit(self, tree: TreeType) -> BinaryTreeSplit[ async def fsplit(self, tree: TreeType) -> BinaryTreeSplit[
ActiveKeyType, MetaDataType, TreeType ActiveKeyType, MetaDataType, TreeType
]: ]:
split = self.split(tree) split: Optional[BinaryTreeSplit[ActiveKeyType, MetaDataType, TreeType]] = await self.split(tree)
assert split is not None assert split is not None
return split 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 raise NotImplementedError

View File

@ -47,5 +47,5 @@ KeyType = TypeVar('KeyType')
class Comparator(Generic[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 raise NotImplementedError

View File

@ -10,7 +10,7 @@ KeyType = TypeVar('KeyType')
class HashComparator(ProtocolComparator[KeyType], Generic[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(original, HashPoint)
assert isinstance(key, HashPoint) assert isinstance(key, HashPoint)
if key.point < original.point: if key.point < original.point:

View File

@ -17,14 +17,14 @@ class KeyedComparator(
self.comparator = comparator self.comparator = comparator
super().__init__() super().__init__()
def compare( async def compare(
self, self,
original: HashPoint[Keyed[ComparatorKeyType]], original: HashPoint[Keyed[ComparatorKeyType]],
key: HashPoint[Keyed[ComparatorKeyType]] key: HashPoint[Keyed[ComparatorKeyType]]
) -> Comparison: ) -> Comparison:
assert isinstance(original, HashPoint) assert isinstance(original, HashPoint)
assert isinstance(key, HashPoint) assert isinstance(key, HashPoint)
return self.comparator.compare( return await self.comparator.compare(
original.resolve().key, (await original.resolve()).key,
key.resolve().key, (await key.resolve()).key,
) )

View File

@ -7,12 +7,12 @@ __all__ = ('PlainComparator',)
class PlainComparator(ProtocolComparator[Plain]): 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(original, HashPoint)
assert isinstance(key, HashPoint) assert isinstance(key, HashPoint)
original_value: Plain = original.resolve() original_value: Plain = await original.resolve()
assert isinstance(original_value, Plain) assert isinstance(original_value, Plain)
key_value: Plain = key.resolve() key_value: Plain = await key.resolve()
assert isinstance(key_value, Plain) assert isinstance(key_value, Plain)
if key_value.source < original_value.source: if key_value.source < original_value.source:
return Left() return Left()

View File

@ -3,6 +3,7 @@ from typing import Generic, Iterable, TypeVar
from nacl.bindings import crypto_hash_sha256 from nacl.bindings import crypto_hash_sha256
from nacl.secret import SecretBox from nacl.secret import SecretBox
from rainbowadn.core.asserts import assert_eq
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.hashresolver import HashResolver
from rainbowadn.core.mentionable import Mentionable from rainbowadn.core.mentionable import Mentionable
@ -43,15 +44,17 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]):
return self.resolution return self.resolution
@classmethod @classmethod
def encrypt(cls, decrypted: EncryptedType, key: bytes) -> 'Encrypted[EncryptedType]': async def encrypt(cls, decrypted: EncryptedType, key: bytes) -> 'Encrypted[EncryptedType]':
assert isinstance(key, bytes) assert isinstance(key, bytes)
hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else () hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else ()
resolution = tuple( resolution: tuple[HashPoint[Encrypted[EncryptedType]], ...] = tuple(
cls.encrypt_hashpoint(hashpoint, key) [
await cls.encrypt_hashpoint(hashpoint, key)
for for
hashpoint hashpoint
in in
hashpoints hashpoints
]
) )
return cls.construct( return cls.construct(
key, key,
@ -61,7 +64,7 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]):
) )
@classmethod @classmethod
def encrypt_hashpoint( async def encrypt_hashpoint(
cls, hashpoint: HashPoint[EncryptedType], key: bytes cls, hashpoint: HashPoint[EncryptedType], key: bytes
) -> HashPoint['Encrypted[EncryptedType]']: ) -> HashPoint['Encrypted[EncryptedType]']:
assert isinstance(hashpoint, HashPoint) assert isinstance(hashpoint, HashPoint)
@ -75,7 +78,7 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]):
resolver.mapping[hashpoint.point], resolver.mapping[hashpoint.point],
key key
).hash_point() ).hash_point()
return HashPoint.of(cls.encrypt(hashpoint.resolve(), key)) return HashPoint.of(await cls.encrypt(await hashpoint.resolve(), key))
@classmethod @classmethod
def construct( def construct(
@ -129,7 +132,7 @@ class EncryptedFactory(RainbowFactory[Encrypted[EncryptedType]], Generic[Encrypt
resolver, resolver,
) )
hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else () 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( resolution: tuple[HashPoint[Encrypted], ...] = tuple(
ResolverOrigin( ResolverOrigin(
EncryptedFactory( EncryptedFactory(
@ -155,9 +158,9 @@ class EncryptedResolver(HashResolver):
self.mapping = mapping self.mapping = mapping
self.key = key self.key = key
def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
assert isinstance(point, bytes) 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) 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 self.hashpoint = hashpoint
super().__init__(self.factory) super().__init__(self.factory)
def resolve(self) -> Encrypted[EncryptedType]: async def resolve(self) -> Encrypted[EncryptedType]:
encrypted = self.hashpoint.resolve() source: Encrypted = await self.hashpoint.resolve()
encrypted = self.factory.from_bytes(bytes(encrypted), ShortcutResolver(encrypted)) encrypted: Encrypted[EncryptedType] = self.factory.from_bytes(bytes(source), ShortcutResolver(source))
assert HashPoint.of(encrypted) == self.hashpoint assert_eq(HashPoint.of(encrypted), self.hashpoint)
return encrypted return encrypted
def hash_point(self) -> HashPoint[Encrypted[EncryptedType]]: def hash_point(self) -> HashPoint[Encrypted[EncryptedType]]:
@ -191,9 +194,9 @@ class ShortcutResolver(HashResolver):
hashpoint.point: hashpoint for hashpoint in encrypted.resolution 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) assert isinstance(point, bytes)
resolved: Encrypted = self.mapping[point].resolve() resolved: Encrypted = await self.mapping[point].resolve()
return ( return (
HashPoint.bytes_of_mentioned(resolved), HashPoint.bytes_of_mentioned(resolved),
ShortcutResolver(resolved) ShortcutResolver(resolved)

View File

@ -1,28 +1,33 @@
from collections import OrderedDict from collections import OrderedDict
from typing import MutableMapping from typing import MutableMapping
from rainbowadn.core.extendableresolver import ExtendableResolver, Mentioned
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.hashresolver import HashResolver
from rainbowadn.core.mentionable import Mentionable from rainbowadn.core.mentionable import Mentionable
from rainbowadn.core.recursivementionable import RecursiveMentionable from rainbowadn.core.recursivementionable import RecursiveMentionable
class DictResolver(HashResolver): class DictResolver(ExtendableResolver):
def __init__(self): def __init__(self):
self.table: MutableMapping[bytes, bytes] = OrderedDict() 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) assert isinstance(point, bytes)
return self.table[point], self 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) assert isinstance(hash_point, HashPoint)
if hash_point.point in self.table: if hash_point.point in self.table:
pass pass
else: else:
value: Mentionable = hash_point.resolve() value: Mentionable = await hash_point.resolve()
assert isinstance(value, Mentionable) assert isinstance(value, Mentionable)
self.table[hash_point.point] = HashPoint.bytes_of_mentioned(value) self.table[hash_point.point] = HashPoint.bytes_of_mentioned(value)
if isinstance(value, RecursiveMentionable): if isinstance(value, RecursiveMentionable):
for hash_point in value.points(): 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

View File

@ -2,5 +2,5 @@ from rainbowadn.core.hashresolver import HashResolver
class FailResolver(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') raise TypeError('fail-resolver always fails')

View File

@ -18,9 +18,13 @@ class Instrumentation:
self.instrument(*args, **kwargs) self.instrument(*args, **kwargs)
return self.method(*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): 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) setattr(self.target, self.methodname, self.method)
del self.method del self.method

View File

@ -9,10 +9,10 @@ import nacl.signing
from rainbowadn.chain.blockchain import BlockChainFactory from rainbowadn.chain.blockchain import BlockChainFactory
from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface
from rainbowadn.chain.reduction.reductionchainmetafactory import ReductionChainMetaFactory 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.hashpoint import HashPoint
from rainbowadn.core.nullability.notnull import NotNull from rainbowadn.core.nullability.notnull import NotNull
from rainbowadn.core.rainbow_factory import RainbowFactory from rainbowadn.core.rainbow_factory import RainbowFactory
from rainbowadn.core.resolvermetaorigin import ResolverMetaOrigin
from rainbowadn.data.atomic.integer import Integer from rainbowadn.data.atomic.integer import Integer
from rainbowadn.data.atomic.plain import Plain from rainbowadn.data.atomic.plain import Plain
from rainbowadn.data.collection.pair import Pair, PairFactory from rainbowadn.data.collection.pair import Pair, PairFactory
@ -32,14 +32,14 @@ from rainbowadn.wrisbt.wrisbtparametres import WrisbtParametres
from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot
class TestAll(unittest.TestCase): class TestAll(unittest.IsolatedAsyncioTestCase):
"""examples rather than real tests""" """examples rather than real tests"""
def test_bankchain(self): async def test_bankchain(self):
with self.subTest('setup'): with self.subTest('setup'):
dr = DictResolver() dr = DictResolver()
with self.subTest('create empty'): with self.subTest('create empty'):
bank = BankChain.empty(ReductionChainMetaFactory()) bank: BankChain = BankChain.empty(ReductionChainMetaFactory().loose())
with self.subTest('prepare transactions'): with self.subTest('prepare transactions'):
key_0 = nacl.signing.SigningKey.generate() key_0 = nacl.signing.SigningKey.generate()
transaction_0 = Transaction.make( transaction_0 = Transaction.make(
@ -47,9 +47,9 @@ class TestAll(unittest.TestCase):
[CoinData.of(Subject(key_0.verify_key), 1_000_000)], [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'): with self.subTest('add transactions'):
bank = bank.adds( bank = await bank.adds(
[ [
transaction_0, transaction_0,
Transaction.make( Transaction.make(
@ -60,22 +60,22 @@ class TestAll(unittest.TestCase):
] ]
) )
with self.subTest('add empty'): with self.subTest('add empty'):
bank = bank.adds( bank = await bank.adds(
[] []
) )
print(bank) print(bank)
with self.subTest('verify'): with self.subTest('verify'):
assert bank.verify() assert_true(await bank.verify())
with self.subTest('recover'): with self.subTest('recover'):
dr.save(HashPoint.of(bank.reference)) await dr.save(HashPoint.of(bank.reference))
bank = BankChain.from_reference( bank = BankChain.from_reference(
ReductionChainMetaFactory(), ResolverMetaOrigin(dr).migrate_resolved(bank.reference) ReductionChainMetaFactory(), await dr.migrate_resolved(bank.reference)
) )
print(bank) print(bank)
with self.subTest('verify'): 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'): with self.subTest('setup'):
stoptime = time.process_time() stoptime = time.process_time()
@ -91,33 +91,33 @@ class TestAll(unittest.TestCase):
n = 2500 n = 2500
keysize = 7 keysize = 7
with self.subTest('create empty'): with self.subTest('create empty'):
btree = WrisbtRoot.empty(WrisbtParametres(1, keysize)) btree: WrisbtRoot = WrisbtRoot.empty(WrisbtParametres(1, keysize))
measure('init') measure('init')
with self.subTest('add keys', n=n): with self.subTest('add keys', n=n):
for _ in range(n): for _ in range(n):
key = os.urandom(keysize) key = os.urandom(keysize)
assert not btree.contains(key) assert_false(await btree.contains(key))
btree = btree.add(key) btree = await btree.add(key)
assert btree.contains(key) assert_true(await btree.contains(key))
measure('add') measure('add')
with self.subTest('save'): with self.subTest('save'):
dr.save(HashPoint.of(btree)) await dr.save(HashPoint.of(btree))
measure('save') measure('save')
with self.subTest('resolve and iterate'): with self.subTest('resolve and iterate'):
btree = ResolverMetaOrigin(dr).migrate_resolved(btree) btree = await dr.migrate_resolved(btree)
assert len(btree.keys()) == n assert_eq(len(await btree.keys()), n)
print(btree.height) print(btree.height)
measure('resolve and iterate') measure('resolve and iterate')
with self.subTest('resolve and add', n=n): with self.subTest('resolve and add', n=n):
for _ in range(n): for _ in range(n):
key = os.urandom(keysize) key = os.urandom(keysize)
assert not btree.contains(key) assert_false(await btree.contains(key))
btree = btree.add(key) btree = await btree.add(key)
assert btree.contains(key) assert_true(await btree.contains(key))
print(btree.height) print(btree.height)
measure('resolve and add') measure('resolve and add')
def test_wrisbt_index(self): async def test_wrisbt_index(self):
with self.subTest('create empty'): with self.subTest('create empty'):
factory: RainbowFactory[Pair[Plain, Plain]] = PairFactory(Plain.factory(), Plain.factory()).loose() factory: RainbowFactory[Pair[Plain, Plain]] = PairFactory(Plain.factory(), Plain.factory()).loose()
chain: ChainCollectionInterface[Any, Pair[Plain, Plain], WrisbtRoot] = BlockChainFactory( chain: ChainCollectionInterface[Any, Pair[Plain, Plain], WrisbtRoot] = BlockChainFactory(
@ -125,7 +125,7 @@ class TestAll(unittest.TestCase):
).empty().loose() ).empty().loose()
with self.subTest('fill'): with self.subTest('fill'):
for _ in range(1000): for _ in range(1000):
chain = chain.add( chain = await chain.add(
HashPoint.of( HashPoint.of(
Pair( Pair(
HashPoint.of(Plain(os.urandom(16))), HashPoint.of(Plain(os.urandom(16))),
@ -134,29 +134,29 @@ class TestAll(unittest.TestCase):
) )
) )
with self.subTest('check'): with self.subTest('check'):
assert chain assert_true(await chain.verify())
with self.subTest('measure height'): with self.subTest('measure height'):
reference = chain.actual_state().reference reference = await chain.actual_state()
assert not reference.null() 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( tree: ActiveBinaryTree[Plain, Integer] = ActiveBinaryTree.empty(
AVL(PlainComparator(Replace())), Plain.factory() AVL(PlainComparator(Replace())), Plain.factory()
) )
for i in range(26): for i in range(26):
tree = tree.add(HashPoint.of(Plain(bytes([ord('A') + i])))) tree = await tree.add(HashPoint.of(Plain(bytes([ord('A') + i]))))
print(tree.reference.str(0)) print(await tree.reference.str(0))
def test_avl_stress(self): async def test_avl_stress(self):
tree: ActiveBinaryTree[Plain, Integer] = ActiveBinaryTree.empty( tree: ActiveBinaryTree[Plain, Integer] = ActiveBinaryTree.empty(
AVL(PlainComparator(Replace())), Plain.factory() AVL(PlainComparator(Replace())), Plain.factory()
) )
for i in range(250): for i in range(250):
tree = tree.add(HashPoint.of(Plain(os.urandom(16)))) tree = await tree.add(HashPoint.of(Plain(os.urandom(16))))
print(tree.loose().reference.resolve().key.resolve().metadata.resolve().integer) 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') instrumentation = Counter(Encrypted, 'encrypt')
with self.subTest('setup'): with self.subTest('setup'):
key = b'a' * 32 key = b'a' * 32
@ -167,29 +167,29 @@ class TestAll(unittest.TestCase):
) )
with self.subTest('fill'): with self.subTest('fill'):
for char in string.ascii_uppercase: for char in string.ascii_uppercase:
tree = tree.add(HashPoint.of(Plain(char.encode()))) tree = await tree.add(HashPoint.of(Plain(char.encode())))
print(tree.reference.str(0)) print(await tree.reference.str(0))
with self.subTest('encrypt'): with self.subTest('encrypt'):
target = tree.reference target = tree.reference
with instrumentation: with instrumentation:
target = Encrypted.encrypt(target, key).decrypted target = (await Encrypted.encrypt(target, key)).decrypted
print(instrumentation.counter) print(instrumentation.counter)
tree = tree.create(target) tree = tree.create(target)
print(tree.reference.str(0)) print(await tree.reference.str(0))
with self.subTest('alter'): with self.subTest('alter'):
tree = tree.add(HashPoint.of(Plain(b'NEWKEY'))) tree = await tree.add(HashPoint.of(Plain(b'NEWKEY')))
tree = tree.remove(HashPoint.of(Plain(b'F'))) tree = await tree.remove(HashPoint.of(Plain(b'F')))
print(tree.reference.str(0)) print(await tree.reference.str(0))
with self.subTest('encrypt and migrate'): with self.subTest('encrypt and migrate'):
target = tree.reference target = tree.reference
with instrumentation: with instrumentation:
eeed = Encrypted.encrypt(target, key) eeed = await Encrypted.encrypt(target, key)
print(instrumentation.counter) print(instrumentation.counter)
dr.save(HashPoint.of(eeed)) await dr.save(HashPoint.of(eeed))
print(ResolverMetaOrigin(dr).migrate_resolved(eeed).decrypted.str(0)) print(await (await dr.migrate_resolved(eeed)).decrypted.str(0))
with self.subTest('re-encrypt'): with self.subTest('re-encrypt'):
new_key = b'b' * 32 new_key = b'b' * 32
target = eeed.decrypted target = eeed.decrypted
with instrumentation: with instrumentation:
Encrypted.encrypt(target, new_key) await Encrypted.encrypt(target, new_key)
print(instrumentation.counter) print(instrumentation.counter)

View File

@ -6,5 +6,5 @@ Referenced = TypeVar('Referenced')
class ThresholdProtocol(Generic[Referenced]): class ThresholdProtocol(Generic[Referenced]):
def threshold(self, referenced: Referenced) -> bytes: async def threshold(self, referenced: Referenced) -> bytes:
raise NotImplementedError raise NotImplementedError

View File

@ -22,9 +22,9 @@ class ValidReference(RecursiveMentionable, Generic[Referenced]):
def points(self) -> Iterable[HashPoint]: def points(self) -> Iterable[HashPoint]:
return [self.reference] return [self.reference]
def resolve(self) -> Referenced: async def resolve(self) -> Referenced:
referenced: Referenced = self.reference.resolve() referenced: Referenced = await self.reference.resolve()
assert self.reference.point < self.protocol.threshold(referenced) assert self.reference.point < (await self.protocol.threshold(referenced))
return referenced return referenced
def __bytes__(self): def __bytes__(self):

View File

@ -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) assert isinstance(stack, NullableReference)
return BankChain( 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) assert isinstance(transactions, list)
return self.add( return await self.add(
Stack.off( Stack.off(
Transaction.factory(), Transaction.factory(),
reversed(transactions) reversed(transactions)
) )
) )
def verify(self) -> bool: async def verify(self) -> bool:
return self.chain.verify() return await self.chain.verify()
def __str__(self):
return self.reference.str(0)

View File

@ -19,22 +19,22 @@ __all__ = ('BankProtocol',)
class BankProtocol(ReductionProtocol[NullableReference[Stack[Transaction]], BankState]): class BankProtocol(ReductionProtocol[NullableReference[Stack[Transaction]], BankState]):
def reduce( async def reduce(
self, self,
reduction: Reduction[NullableReference[Stack[Transaction]], BankState] reduction: Reduction[NullableReference[Stack[Transaction]], BankState]
) -> ReductionResult[NullableReference[Stack[Transaction]], BankState]: ) -> ReductionResult[NullableReference[Stack[Transaction]], BankState]:
assert isinstance(reduction, Reduction) assert isinstance(reduction, Reduction)
bank_state: BankState = reduction.accumulator.resolve() bank_state: BankState = await reduction.accumulator.resolve()
assert isinstance(bank_state, BankState) assert isinstance(bank_state, BankState)
reference: NullableReference[Stack[Transaction]] = reduction.reductor.resolve() reference: NullableReference[Stack[Transaction]] = await reduction.reductor.resolve()
if reference.null(): if reference.null():
return Reduced(HashPoint.of(bank_state.without_miner())) return Reduced(HashPoint.of(bank_state.without_miner()))
else: else:
stack: Stack[Transaction] = reference.resolve() stack: Stack[Transaction] = await reference.resolve()
assert isinstance(stack, Stack) assert isinstance(stack, Stack)
return Reduction( return Reduction(
HashPoint.of(stack.previous), 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]: 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) assert isinstance(state, HashPoint)
return HashPoint.of(state.resolve().without_miner().advance()) return HashPoint.of(await (await state.resolve()).without_miner().advance())

View File

@ -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.hash_point_format import hash_point_format, tabulate
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.hashresolver import HashResolver
@ -79,12 +80,12 @@ class BankState(RecursiveMentionable, StaticMentionable):
self.length self.length
) )
def advance(self) -> 'BankState': async def advance(self) -> 'BankState':
return BankState( return BankState(
self.minted, self.minted,
self.used, self.used,
NullableReference(Null(), self.miner.factory), 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]: def minted_tree(self) -> ActiveBinaryTree[Coin, Integer]:
@ -97,25 +98,25 @@ class BankState(RecursiveMentionable, StaticMentionable):
AVL(HashComparator(Fail())), self.used 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() minted: ActiveBinaryTree[Coin, Integer] = self.minted_tree()
used: ActiveBinaryTree[Coin, Integer] = self.used_tree() used: ActiveBinaryTree[Coin, Integer] = self.used_tree()
for in_coin in coins: async for in_coin in coins:
assert minted.contains(in_coin) assert_true(await minted.contains(in_coin))
assert not used.contains(in_coin) assert_false(await used.contains(in_coin))
used = used.add(in_coin) used = await used.add(in_coin)
return BankState(self.minted, used.reference, self.miner, self.length) return BankState(self.minted, used.reference, self.miner, self.length)
def mint_coins( async def mint_coins(
self, self,
transaction: Transaction transaction: Transaction
) -> 'BankState': ) -> 'BankState':
assert self.verify(transaction) assert_true(await self.verify(transaction))
miner = self.miner_nullable() miner = self.miner_nullable()
minted: ActiveBinaryTree[Coin, Integer] = self.minted_tree() minted: ActiveBinaryTree[Coin, Integer] = self.minted_tree()
for coin, miner in transaction.iter_coins(self.mint(), miner): async for coin, miner in transaction.iter_coins(self.mint(), miner):
assert not minted.contains(HashPoint.of(coin)) assert_false(await minted.contains(HashPoint.of(coin)))
minted = minted.add(HashPoint.of(coin)) minted = await minted.add(HashPoint.of(coin))
assert isinstance(minted, ActiveBinaryTree) assert isinstance(minted, ActiveBinaryTree)
return BankState(minted.reference, self.used, NullableReference(miner, self.miner.factory), self.length) return BankState(minted.reference, self.used, NullableReference(miner, self.miner.factory), self.length)
@ -128,32 +129,34 @@ class BankState(RecursiveMentionable, StaticMentionable):
else: else:
return 0 return 0
def verify(self, transaction: Transaction) -> bool: async def verify(self, transaction: Transaction) -> bool:
assert isinstance(transaction, Transaction) assert isinstance(transaction, Transaction)
assert transaction.verify(self.mint()) assert_true(await transaction.verify(self.mint()))
return True return True
def _push(self, transaction: Transaction) -> 'BankState': async def _push(self, transaction: Transaction) -> 'BankState':
assert isinstance(transaction, Transaction) assert isinstance(transaction, Transaction)
return self.use_coins( return await (
transaction.data_resolved().iter_in_coins() await self.use_coins(
(await transaction.data_resolved()).iter_in_coins()
)
).mint_coins( ).mint_coins(
transaction transaction
) )
def push(self, transaction: HashPoint[Transaction]) -> 'BankState': async def push(self, transaction: HashPoint[Transaction]) -> 'BankState':
return self._push(transaction.resolve()) return await self._push(await transaction.resolve())
def str(self, tab: int) -> str: async def str(self, tab: int) -> str:
assert isinstance(tab, int) assert isinstance(tab, int)
return f'(' \ return f'(' \
f'{tabulate(tab + 1)}bank' \ f'{tabulate(tab + 1)}bank' \
f'{tabulate(tab + 1)}(miner)' \ 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)}(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)}(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)}(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)})' f'{tabulate(tab)})'

View File

@ -2,6 +2,7 @@ import nacl.bindings
import nacl.exceptions import nacl.exceptions
import nacl.signing import nacl.signing
from rainbowadn.core.asserts import assert_eq
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.data.atomic.atomic import Atomic from rainbowadn.data.atomic.atomic import Atomic
from rainbowadn.v13.subject import Subject from rainbowadn.v13.subject import Subject
@ -16,7 +17,7 @@ class BadSignature(nacl.exceptions.BadSignatureError):
class Signature(Atomic): class Signature(Atomic):
def __init__(self, source: bytes): def __init__(self, source: bytes):
assert isinstance(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 self.source = source
@classmethod @classmethod

View File

@ -1,7 +1,8 @@
from typing import Iterable from typing import AsyncIterable, Iterable
import nacl.signing import nacl.signing
from rainbowadn.core.asserts import assert_true
from rainbowadn.core.hash_point_format import hash_point_format, tabulate from rainbowadn.core.hash_point_format import hash_point_format, tabulate
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.hashresolver import HashResolver
@ -31,8 +32,8 @@ class CoinData(RecursiveMentionable, StaticMentionable):
self.owner = owner self.owner = owner
self.value = value self.value = value
def int_value(self) -> int: async def int_value(self) -> int:
return self.value.resolve().integer return (await self.value.resolve()).integer
@classmethod @classmethod
def of(cls, owner: Subject, value: int) -> 'CoinData': 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(), 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) assert isinstance(tab, int)
return f'{hash_point_format(self.owner, tab)}' \ return f'{await hash_point_format(self.owner, tab)}' \
f'{tabulate(tab)}{hash_point_format(self.value, tab)}' f'{tabulate(tab)}{await hash_point_format(self.value, tab)}'
class Coin(RecursiveMentionable, StaticMentionable): class Coin(RecursiveMentionable, StaticMentionable):
@ -75,8 +76,8 @@ class Coin(RecursiveMentionable, StaticMentionable):
self.origin = origin self.origin = origin
self.index = index self.index = index
def data_resolved(self) -> CoinData: async def data_resolved(self) -> CoinData:
return self.data.resolve() return await self.data.resolve()
def points(self) -> Iterable[HashPoint]: def points(self) -> Iterable[HashPoint]:
return [self.data, self.origin, self.index] 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(), 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) assert isinstance(tab, int)
return f'(' \ return f'(' \
f'{tabulate(tab + 1)}coin' \ 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)}(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)})' f'{tabulate(tab)})'
@ -138,59 +139,65 @@ class TransactionData(RecursiveMentionable, StaticMentionable):
).from_bytes(source[HashPoint.HASH_LENGTH:], resolver), ).from_bytes(source[HashPoint.HASH_LENGTH:], resolver),
) )
def _verify_signatures( async def _verify_signatures(
self, self,
signatures: NullableReference[Stack[Signature]] signatures: NullableReference[Stack[Signature]]
) -> bool: ) -> bool:
for coin, signature in zip(self.iter_in_coins_resolved(), Stack.iter(signatures), strict=True): for coin, signature in zip(
assert signature.resolve().verify( [x async for x in self.iter_in_coins_resolved()],
coin.data_resolved().owner.resolve(), [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 self.hash_point
) )
)
return True return True
def iter_in_coins(self) -> Iterable[HashPoint[Coin]]: def iter_in_coins(self) -> AsyncIterable[HashPoint[Coin]]:
return Stack.iter(self.in_coins) return Stack.iter(self.in_coins)
def iter_in_coins_resolved(self) -> Iterable[Coin]: async def iter_in_coins_resolved(self) -> AsyncIterable[Coin]:
for coin in Stack.iter(self.in_coins): async for coin in self.iter_in_coins():
yield coin.resolve() yield await coin.resolve()
def _total_in(self) -> int: async def _total_in(self) -> int:
return sum(coin.data_resolved().int_value() for coin in self.iter_in_coins_resolved()) 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) return Stack.iter(self.out_coins)
def _total_out(self) -> int: async def _total_out(self) -> int:
return sum(coin.resolve().int_value() for coin in self.iter_out_coins()) 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 isinstance(mint, int)
assert self._total_out() <= self._total_in() + mint assert (await self.extra(mint)) >= 0
return True return True
def extra(self, mint: int) -> int: async def extra(self, mint: int) -> int:
assert isinstance(mint, 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, self,
signatures: NullableReference[Stack[Signature]], signatures: NullableReference[Stack[Signature]],
mint: int mint: int
) -> bool: ) -> bool:
assert isinstance(signatures, NullableReference) assert isinstance(signatures, NullableReference)
assert isinstance(mint, int) assert isinstance(mint, int)
assert self._verify_signatures(signatures) assert_true(await self._verify_signatures(signatures))
assert self._verify_values(mint) assert_true(await self._verify_values(mint))
return True return True
def str(self, tab: int) -> str: async def str(self, tab: int) -> str:
assert isinstance(tab, int) assert isinstance(tab, int)
return f'(in)' \ 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)}(out)' \
f'{tabulate(tab)}{self.out_coins.str(tab)}' f'{tabulate(tab)}{await self.out_coins.str(tab)}'
class Transaction(RecursiveMentionable, StaticMentionable): class Transaction(RecursiveMentionable, StaticMentionable):
@ -206,8 +213,8 @@ class Transaction(RecursiveMentionable, StaticMentionable):
self.hash_point = HashPoint.of(self) self.hash_point = HashPoint.of(self)
assert isinstance(self.hash_point, HashPoint) assert isinstance(self.hash_point, HashPoint)
def data_resolved(self) -> TransactionData: async def data_resolved(self) -> TransactionData:
return self.data.resolve() return await self.data.resolve()
def points(self) -> Iterable[HashPoint]: def points(self) -> Iterable[HashPoint]:
return [self.data, *self.signatures.points()] return [self.data, *self.signatures.points()]
@ -228,19 +235,19 @@ class Transaction(RecursiveMentionable, StaticMentionable):
NullableReferenceFactory(stack_factory).from_bytes(source[HashPoint.HASH_LENGTH:], resolver), NullableReferenceFactory(stack_factory).from_bytes(source[HashPoint.HASH_LENGTH:], resolver),
) )
def iter_coins( async def iter_coins(
self, self,
mint: int, mint: int,
miner: Nullable[HashPoint[Subject]] miner: Nullable[HashPoint[Subject]]
) -> Iterable[tuple[Coin, Nullable[HashPoint[Subject]]]]: ) -> AsyncIterable[tuple[Coin, Nullable[HashPoint[Subject]]]]:
transaction_data: TransactionData = self.data_resolved() transaction_data: TransactionData = await self.data_resolved()
assert isinstance(transaction_data, TransactionData) assert isinstance(transaction_data, TransactionData)
index = 0 index = 0
out_coin: HashPoint[CoinData] 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) assert isinstance(out_coin, HashPoint)
if miner.null(): if miner.null():
miner = NotNull(out_coin.resolve().owner) miner = NotNull((await out_coin.resolve()).owner)
assert isinstance(miner, Nullable) assert isinstance(miner, Nullable)
coin: Coin = Coin(out_coin, self.hash_point, HashPoint.of(Integer(index))) coin: Coin = Coin(out_coin, self.hash_point, HashPoint.of(Integer(index)))
assert isinstance(coin, Coin) assert isinstance(coin, Coin)
@ -251,7 +258,7 @@ class Transaction(RecursiveMentionable, StaticMentionable):
HashPoint.of( HashPoint.of(
CoinData( CoinData(
miner.resolve(), miner.resolve(),
HashPoint.of(Integer(transaction_data.extra(mint))) HashPoint.of(Integer(await transaction_data.extra(mint)))
) )
), ),
self.hash_point, self.hash_point,
@ -260,23 +267,23 @@ class Transaction(RecursiveMentionable, StaticMentionable):
assert isinstance(coin, Coin) assert isinstance(coin, Coin)
yield coin, miner yield coin, miner
def coins( async def coins(
self, self,
mint: int, mint: int,
miner: Nullable[HashPoint[Subject]] miner: Nullable[HashPoint[Subject]]
) -> list[Coin]: ) -> list[Coin]:
assert isinstance(mint, int) assert isinstance(mint, int)
assert isinstance(miner, Nullable) 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) assert isinstance(mint, int)
data: TransactionData = self.data_resolved() data: TransactionData = await self.data_resolved()
assert isinstance(data, TransactionData) assert isinstance(data, TransactionData)
assert data.verify(self.signatures, mint) assert_true(await data.verify(self.signatures, mint))
return True return True
def str(self, tab: int) -> str: async def str(self, tab: int) -> str:
assert isinstance(tab, int) assert isinstance(tab, int)
return f'(' \ return f'(' \
f'{tabulate(tab + 1)}transaction' \ f'{tabulate(tab + 1)}transaction' \

View File

@ -1,6 +1,7 @@
import bisect 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.hash_point_format import hash_point_format, tabulate
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.hashresolver import HashResolver
@ -47,7 +48,7 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable):
else: else:
self.keys = self.length // (parametres.keysize + HashPoint.HASH_LENGTH) self.keys = self.length // (parametres.keysize + HashPoint.HASH_LENGTH)
self.children = self.keys + 1 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.parametres = parametres
self.keymin = parametres.keymin self.keymin = parametres.keymin
@ -60,7 +61,7 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable):
self.keyend = self.keys * self.keysize self.keyend = self.keys * self.keysize
assert len(cache) == self.children assert_eq(len(cache), self.children)
self.cache = cache self.cache = cache
def full(self) -> bool: def full(self) -> bool:
@ -95,11 +96,11 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable):
self.bytes_no(index, self.keyend, HashPoint.HASH_LENGTH) 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 isinstance(index, int)
assert 0 <= index < self.children assert 0 <= index < self.children
assert not self.leaf assert not self.leaf
return self.child_no(index).resolve() return await self.child_no(index).resolve()
def balanced(self) -> bool: def balanced(self) -> bool:
return self.keys <= 2 * self.keymin return self.keys <= 2 * self.keymin
@ -157,7 +158,7 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable):
self.range(self.keymin + 1, 2 * self.keymin + 1), 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) assert isinstance(tab, int)
formatted = f'{self.height}' \ formatted = f'{self.height}' \
@ -165,14 +166,14 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable):
for key_index in range(self.keys): for key_index in range(self.keys):
formatted += f'{tabulate(tab + 1)}{self.key_no(key_index).hex()}' formatted += f'{tabulate(tab + 1)}{self.key_no(key_index).hex()}'
for child_index in range(self.children): 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}' \ return f'{formatted}' \
f'{tabulate(tab)})' f'{tabulate(tab)})'
def contains(self, key: bytes) -> bool: async def contains(self, key: bytes) -> bool:
assert isinstance(key, bytes) assert isinstance(key, bytes)
assert len(key) == self.keysize assert_eq(len(key), self.keysize)
assert self.balanced() assert self.balanced()
@ -187,13 +188,13 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable):
assert key > self.key_no(index - 1) assert key > self.key_no(index - 1)
if self.leaf: if self.leaf:
return False return False
child: WeakReferenceIndexSetBTree = self.child_resolved_no(index) child: WeakReferenceIndexSetBTree = await self.child_resolved_no(index)
assert isinstance(child, WeakReferenceIndexSetBTree) 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 isinstance(key, bytes)
assert len(key) == self.keysize assert_eq(len(key), self.keysize)
assert self.balanced() assert self.balanced()
@ -214,9 +215,9 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable):
self.root, self.root,
() ()
) )
child: WeakReferenceIndexSetBTree = self.child_resolved_no(index) child: WeakReferenceIndexSetBTree = await self.child_resolved_no(index)
assert isinstance(child, WeakReferenceIndexSetBTree) assert isinstance(child, WeakReferenceIndexSetBTree)
child: WeakReferenceIndexSetBTree = child.add(key) child: WeakReferenceIndexSetBTree = await child.add(key)
assert isinstance(child, WeakReferenceIndexSetBTree) assert isinstance(child, WeakReferenceIndexSetBTree)
if child.full(): if child.full():
left, middle, right = child.split() 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: if self.leaf:
for key_index in range(self.keys): for key_index in range(self.keys):
yield self.key_no(key_index) yield self.key_no(key_index)
@ -279,7 +280,8 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable):
if mode: if mode:
yield self.key_no(real_index) yield self.key_no(real_index)
else: 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]): class KeyView(Sequence[WeakReferenceIndexSetBTree]):

View File

@ -40,6 +40,6 @@ class WrisbtChainProtocol(
def actual_state_factory(self) -> RainbowFactory[WrisbtRoot]: def actual_state_factory(self) -> RainbowFactory[WrisbtRoot]:
return WrisbtRootFactory(WrisbtParametres(self.keymin, HashPoint.HASH_LENGTH)) 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) assert isinstance(state, WrisbtIndex)
return state.total return state.total

View File

@ -36,11 +36,11 @@ class WrisbtIndex(RecursiveMentionable):
def __factory__(self) -> RainbowFactory['WrisbtIndex']: def __factory__(self) -> RainbowFactory['WrisbtIndex']:
return WrisbtIndexFactory(self.keymin) return WrisbtIndexFactory(self.keymin)
def str(self, tab: int) -> str: async def str(self, tab: int) -> str:
assert isinstance(tab, int) assert isinstance(tab, int)
return f'(index)' \ return f'(index)' \
f'{tabulate(tab)}{hash_point_format(self.total, tab)}' \ f'{tabulate(tab)}{await hash_point_format(self.total, tab)}' \
f'{tabulate(tab)}{hash_point_format(self.delta, tab)}' f'{tabulate(tab)}{await hash_point_format(self.delta, tab)}'
class WrisbtIndexFactory(RainbowFactory[WrisbtIndex]): class WrisbtIndexFactory(RainbowFactory[WrisbtIndex]):

View File

@ -26,25 +26,25 @@ class WrisbtProtocol(MetaReductionStateProtocol[TargetType, WrisbtIndex]):
) )
) )
def _derive( async def _derive(
self, self,
previous: HashPoint[WrisbtIndex], previous: HashPoint[WrisbtIndex],
header: HashPoint[TargetType] header: HashPoint[TargetType]
) -> HashPoint[WrisbtIndex]: ) -> HashPoint[WrisbtIndex]:
assert isinstance(previous, HashPoint) assert isinstance(previous, HashPoint)
assert isinstance(header, HashPoint) assert isinstance(header, HashPoint)
index: WrisbtIndex = previous.resolve() index: WrisbtIndex = await previous.resolve()
assert isinstance(index, WrisbtIndex) assert isinstance(index, WrisbtIndex)
empty: WrisbtRoot = WrisbtRoot.empty(WrisbtParametres(self.keymin, HashPoint.HASH_LENGTH)) empty: WrisbtRoot = WrisbtRoot.empty(WrisbtParametres(self.keymin, HashPoint.HASH_LENGTH))
assert isinstance(empty, WrisbtRoot) assert isinstance(empty, WrisbtRoot)
total: WrisbtRoot = index.total.resolve() total: WrisbtRoot = await index.total.resolve()
assert isinstance(total, WrisbtRoot) assert isinstance(total, WrisbtRoot)
return HashPoint.of( return HashPoint.of(
WrisbtIndex( WrisbtIndex(
HashPoint.of(total.index(header, empty)), HashPoint.of(await total.index(header, empty)),
HashPoint.of(empty.index(header, total)), HashPoint.of(await empty.index(header, total)),
index.keymin index.keymin
) )
) )

View File

@ -1,5 +1,6 @@
from typing import Iterable 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.hash_point_format import hash_point_format, tabulate
from rainbowadn.core.hashpoint import HashPoint from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.hashresolver import HashResolver from rainbowadn.core.hashresolver import HashResolver
@ -25,8 +26,8 @@ class WrisbtRoot(RecursiveMentionable):
self.height = height self.height = height
self.parametres = parametres self.parametres = parametres
def root_resolved(self) -> 'WeakReferenceIndexSetBTree': async def root_resolved(self) -> 'WeakReferenceIndexSetBTree':
return self.root.resolve() return await self.root.resolve()
def points(self) -> Iterable[HashPoint]: def points(self) -> Iterable[HashPoint]:
return [self.root] return [self.root]
@ -42,26 +43,26 @@ class WrisbtRoot(RecursiveMentionable):
assert isinstance(parametres, WrisbtParametres) assert isinstance(parametres, WrisbtParametres)
return WrisbtRoot(HashPoint.of(WeakReferenceIndexSetBTree(b'', 0, parametres, True, ())), 0, parametres) 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) assert isinstance(tab, int)
return f'(root)' \ return f'(root)' \
f'{tabulate(tab)}{self.height}' \ 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 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) 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 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) assert isinstance(root, WeakReferenceIndexSetBTree)
if root.full(): if root.full():
@ -84,25 +85,25 @@ class WrisbtRoot(RecursiveMentionable):
assert isinstance(root, WeakReferenceIndexSetBTree) assert isinstance(root, WeakReferenceIndexSetBTree)
return cls(HashPoint.of(root), root.height, root.parametres) return cls(HashPoint.of(root), root.height, root.parametres)
def keys(self) -> list[bytes]: async def keys(self) -> list[bytes]:
return list(self.root_resolved().iter_keys()) return list([x async for x in (await self.root_resolved()).iter_keys()])
def index( async def index(
self, target: HashPoint, exclude: 'WrisbtRoot' self, target: HashPoint, exclude: 'WrisbtRoot'
) -> 'WrisbtRoot': ) -> 'WrisbtRoot':
assert isinstance(target, HashPoint) assert isinstance(target, HashPoint)
assert isinstance(exclude, WrisbtRoot) assert isinstance(exclude, WrisbtRoot)
key: bytes = target.point key: bytes = target.point
assert isinstance(key, bytes) assert isinstance(key, bytes)
if exclude.contains(key) or self.contains(key): if await exclude.contains(key) or await self.contains(key):
return self return self
tree = self tree: WrisbtRoot = self
value: Mentionable = target.resolve() value: Mentionable = await target.resolve()
assert isinstance(value, Mentionable) assert isinstance(value, Mentionable)
if isinstance(value, RecursiveMentionable): if isinstance(value, RecursiveMentionable):
for hash_point in value.points(): for hash_point in value.points():
tree = tree.index(hash_point, exclude) tree = await tree.index(hash_point, exclude)
tree = tree.add(key) tree = await tree.add(key)
return tree return tree