async
This commit is contained in:
parent
69297cdac1
commit
cf727d87b0
@ -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)})'
|
||||||
|
|
||||||
|
|
||||||
|
@ -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[
|
||||||
|
@ -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]:
|
||||||
|
@ -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]':
|
||||||
|
@ -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
|
||||||
|
@ -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(
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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]:
|
||||||
|
@ -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()))
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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]]):
|
||||||
|
@ -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]
|
||||||
|
@ -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
|
||||||
|
@ -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],
|
||||||
|
@ -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)
|
||||||
|
@ -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],
|
||||||
|
24
rainbowadn/core/asserts.py
Normal file
24
rainbowadn/core/asserts.py
Normal 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
|
20
rainbowadn/core/extendableresolver.py
Normal file
20
rainbowadn/core/extendableresolver.py
Normal 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()
|
@ -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)
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
|
@ -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]):
|
||||||
|
@ -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
|
||||||
|
@ -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__})'
|
||||||
|
|
||||||
|
@ -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()
|
|
||||||
|
@ -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]:
|
||||||
|
@ -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)})'
|
||||||
|
|
||||||
|
@ -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(
|
||||||
|
@ -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(
|
||||||
|
@ -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]):
|
||||||
|
@ -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
|
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
@ -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
|
||||||
|
@ -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]):
|
||||||
|
@ -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]
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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,
|
||||||
)
|
)
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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')
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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)
|
|
||||||
|
@ -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())
|
||||||
|
@ -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)})'
|
||||||
|
@ -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
|
||||||
|
@ -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' \
|
||||||
|
@ -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]):
|
||||||
|
@ -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
|
||||||
|
@ -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]):
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user