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,
)
def str(self, tab: int) -> str:
async def str(self, tab: int) -> str:
assert isinstance(tab, int)
return f'{self.previous.str(tab)}' \
return f'{await self.previous.str(tab)}' \
f'{tabulate(tab)}(' \
f'{tabulate(tab + 1)}block' \
f'{tabulate(tab + 1)}(header)' \
f'{tabulate(tab + 1)}{hash_point_format(self.header, tab + 1)}' \
f'{tabulate(tab + 1)}{await hash_point_format(self.header, tab + 1)}' \
f'{tabulate(tab + 1)}(state)' \
f'{tabulate(tab + 1)}{hash_point_format(self.state, tab + 1)}' \
f'{tabulate(tab + 1)}{await hash_point_format(self.state, tab + 1)}' \
f'{tabulate(tab)})'

View File

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

View File

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

View File

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

View File

@ -20,8 +20,11 @@ class ChainCollectionInterface(
Generic[BlockType, HeaderType, ActualStateType],
abc.ABC
):
def add(self, header: HashPoint[HeaderType]) -> 'ChainCollectionInterface[BlockType, HeaderType, ActualStateType]':
async def add(
self,
header: HashPoint[HeaderType]
) -> 'ChainCollectionInterface[BlockType, HeaderType, ActualStateType]':
raise NotImplementedError
def verify(self) -> bool:
async def verify(self) -> bool:
raise NotImplementedError

View File

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

View File

@ -50,3 +50,13 @@ class ReductionChainMetaFactory(
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]:
return self.accumulator_factory
def actual_state(
async def actual_state(
self,
state: StateStage[
ReductorType,

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@ StateType = TypeVar('StateType')
class StateProtocol(Generic[HeaderType, StateType]):
def verify(
async def verify(
self,
previous: NullableReference[StateType],
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.mentionable import Mentionable
from rainbowadn.core.recursivementionable import RecursiveMentionable
__all__ = ('hash_point_format', 'tabulate',)
def hash_point_format(hash_point: HashPoint, tab: int) -> str:
async def hash_point_format(hash_point: HashPoint, tab: int) -> str:
assert isinstance(hash_point, HashPoint)
assert isinstance(tab, int)
value = hash_point.resolve()
value: Mentionable = await hash_point.resolve()
if isinstance(value, RecursiveMentionable):
return value.str(tab)
return await value.str(tab)
else:
return str(value)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
from typing import Generic, TypeVar
from rainbowadn.core.asserts import assert_eq
from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.hashresolver import HashResolver
from rainbowadn.core.metaorigin import MetaOrigin
@ -20,12 +21,5 @@ class ResolverMetaOrigin(MetaOrigin[Mentioned], Generic[Mentioned]):
def origin(self, factory: RainbowFactory[Mentioned], point: bytes) -> Origin[Mentioned]:
assert isinstance(factory, RainbowFactory)
assert isinstance(point, bytes)
assert len(point) == HashPoint.HASH_LENGTH
assert_eq(len(point), HashPoint.HASH_LENGTH)
return ResolverOrigin(factory, point, self.resolver)
def migrate(self, hash_point: HashPoint[Mentioned]) -> HashPoint[Mentioned]:
assert isinstance(hash_point, HashPoint)
return self.hash_point(hash_point.factory, hash_point.point)
def migrate_resolved(self, mentioned: Mentioned) -> Mentioned:
return self.migrate(HashPoint.of(mentioned)).resolve()

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,15 +25,15 @@ class BalancedTreeCreationProtocol(
self.protocol = protocol
super().__init__(protocol.comparator)
def _tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
async def _tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
raise NotImplementedError
def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
async def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
assert isinstance(key, HashPoint)
return self.protocol.balance(
self._tree(
self.protocol.balance(treel, self),
self.protocol.balance(treer, self),
return await self.protocol.balance(
await self._tree(
await self.protocol.balance(treel, self),
await self.protocol.balance(treer, self),
key
),
self

View File

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

View File

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

View File

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

View File

@ -47,5 +47,5 @@ KeyType = TypeVar('KeyType')
class Comparator(Generic[KeyType]):
def compare(self, original: HashPoint[KeyType], key: HashPoint[KeyType]) -> Comparison:
async def compare(self, original: HashPoint[KeyType], key: HashPoint[KeyType]) -> Comparison:
raise NotImplementedError

View File

@ -10,7 +10,7 @@ KeyType = TypeVar('KeyType')
class HashComparator(ProtocolComparator[KeyType], Generic[KeyType]):
def compare(self, original: HashPoint[KeyType], key: HashPoint[KeyType]) -> Comparison:
async def compare(self, original: HashPoint[KeyType], key: HashPoint[KeyType]) -> Comparison:
assert isinstance(original, HashPoint)
assert isinstance(key, HashPoint)
if key.point < original.point:

View File

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

View File

@ -7,12 +7,12 @@ __all__ = ('PlainComparator',)
class PlainComparator(ProtocolComparator[Plain]):
def compare(self, original: HashPoint[Plain], key: HashPoint[Plain]) -> Comparison:
async def compare(self, original: HashPoint[Plain], key: HashPoint[Plain]) -> Comparison:
assert isinstance(original, HashPoint)
assert isinstance(key, HashPoint)
original_value: Plain = original.resolve()
original_value: Plain = await original.resolve()
assert isinstance(original_value, Plain)
key_value: Plain = key.resolve()
key_value: Plain = await key.resolve()
assert isinstance(key_value, Plain)
if key_value.source < original_value.source:
return Left()

View File

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

View File

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

View File

@ -2,5 +2,5 @@ from rainbowadn.core.hashresolver import HashResolver
class FailResolver(HashResolver):
def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
raise TypeError('fail-resolver always fails')

View File

@ -18,9 +18,13 @@ class Instrumentation:
self.instrument(*args, **kwargs)
return self.method(*args, **kwargs)
setattr(self.target, self.methodname, wrap)
self.wrap = wrap
setattr(self.target, self.methodname, self.wrap)
def __exit__(self, exc_type, exc_val, exc_tb):
assert getattr(self.target, self.methodname) is self.wrap
del self.wrap
setattr(self.target, self.methodname, self.method)
del self.method

View File

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

View File

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

View File

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

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

View File

@ -19,22 +19,22 @@ __all__ = ('BankProtocol',)
class BankProtocol(ReductionProtocol[NullableReference[Stack[Transaction]], BankState]):
def reduce(
async def reduce(
self,
reduction: Reduction[NullableReference[Stack[Transaction]], BankState]
) -> ReductionResult[NullableReference[Stack[Transaction]], BankState]:
assert isinstance(reduction, Reduction)
bank_state: BankState = reduction.accumulator.resolve()
bank_state: BankState = await reduction.accumulator.resolve()
assert isinstance(bank_state, BankState)
reference: NullableReference[Stack[Transaction]] = reduction.reductor.resolve()
reference: NullableReference[Stack[Transaction]] = await reduction.reductor.resolve()
if reference.null():
return Reduced(HashPoint.of(bank_state.without_miner()))
else:
stack: Stack[Transaction] = reference.resolve()
stack: Stack[Transaction] = await reference.resolve()
assert isinstance(stack, Stack)
return Reduction(
HashPoint.of(stack.previous),
HashPoint.of(bank_state.push(stack.element))
HashPoint.of(await bank_state.push(stack.element))
)
def initial(self, factory: RainbowFactory[BankState]) -> HashPoint[BankState]:
@ -54,6 +54,6 @@ class BankProtocol(ReductionProtocol[NullableReference[Stack[Transaction]], Bank
)
)
def header_filter(self, state: HashPoint[BankState]) -> HashPoint[BankState]:
async def header_filter(self, state: HashPoint[BankState]) -> HashPoint[BankState]:
assert isinstance(state, HashPoint)
return HashPoint.of(state.resolve().without_miner().advance())
return HashPoint.of(await (await state.resolve()).without_miner().advance())

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

View File

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

View File

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

View File

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

View File

@ -40,6 +40,6 @@ class WrisbtChainProtocol(
def actual_state_factory(self) -> RainbowFactory[WrisbtRoot]:
return WrisbtRootFactory(WrisbtParametres(self.keymin, HashPoint.HASH_LENGTH))
def actual_state(self, state: WrisbtIndex) -> HashPoint[WrisbtRoot]:
async def actual_state(self, state: WrisbtIndex) -> HashPoint[WrisbtRoot]:
assert isinstance(state, WrisbtIndex)
return state.total

View File

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

View File

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

View File

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