wrisbt + better bst + better blockchain

This commit is contained in:
AF 2022-05-17 00:12:19 +03:00
parent 244997690d
commit c743da7bb6
43 changed files with 1580 additions and 793 deletions

71
main.py
View File

@ -1,9 +1,20 @@
import os
import time
from collections import OrderedDict from collections import OrderedDict
from typing import MutableMapping from typing import Any, MutableMapping
import nacl.signing import nacl.signing
from rainbowadn.chain.blockchain import BlockChainFactory
from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface
from rainbowadn.chain.reduction.reductionchainmetafactory import ReductionChainMetaFactory from rainbowadn.chain.reduction.reductionchainmetafactory import ReductionChainMetaFactory
from rainbowadn.data.atomic.integer import Integer
from rainbowadn.data.atomic.plain import Plain
from rainbowadn.data.collection.array.array import Array
from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinaryTree
from rainbowadn.data.collection.trees.binary.avl import AVLBTBP
from rainbowadn.data.collection.trees.comparison.comparator import Replace
from rainbowadn.data.collection.trees.comparison.plaincomparator import PlainComparator
from rainbowadn.hashing.hashmentionable import HashMentionable from rainbowadn.hashing.hashmentionable import HashMentionable
from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver from rainbowadn.hashing.hashresolver import HashResolver
@ -13,6 +24,8 @@ from rainbowadn.v13.algo import MINT_CONST
from rainbowadn.v13.bankchain import BankChain from rainbowadn.v13.bankchain import BankChain
from rainbowadn.v13.subject import Subject from rainbowadn.v13.subject import Subject
from rainbowadn.v13.transaction import CoinData, Transaction from rainbowadn.v13.transaction import CoinData, Transaction
from rainbowadn.wrisbt.wrisbtchainprotocol import WrisbtChainProtocol
from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot
class DumbResolver(HashResolver): class DumbResolver(HashResolver):
@ -37,7 +50,7 @@ class DumbResolver(HashResolver):
raise TypeError raise TypeError
def main(): def main0():
dr = DumbResolver() dr = DumbResolver()
bank = BankChain.empty(ReductionChainMetaFactory(), dr) bank = BankChain.empty(ReductionChainMetaFactory(), dr)
key_0 = nacl.signing.SigningKey.generate() key_0 = nacl.signing.SigningKey.generate()
@ -66,8 +79,58 @@ def main():
bank = BankChain.from_reference(ReductionChainMetaFactory(), dr.resolve(HashPoint.of(bank.reference).loose()), dr) bank = BankChain.from_reference(ReductionChainMetaFactory(), dr.resolve(HashPoint.of(bank.reference).loose()), dr)
print(bank) print(bank)
print(bank.verify()) print(bank.verify())
for key, value in dr.table.items(): # for key, value in dr.table.items():
print(key.hex(), value.hex()) # print(key.hex(), value.hex())
def main1():
stoptime = time.process_time()
def measure(message: str):
nonlocal stoptime
now = time.process_time()
print(message, now - stoptime)
stoptime = now
dr = DumbResolver()
btree = WrisbtRoot.empty(16)
measure('init')
for _ in range(10000):
btree = btree.add(dr, HashPoint.hash(os.urandom(32)))
btree = btree.add(dr, HashPoint.hash(b'aaa'))
print(btree.contains(dr, HashPoint.hash(b'aaa')))
measure('add')
dr.save(HashPoint.of(btree))
measure('save')
btree = dr.resolve(HashPoint.of(btree).loose())
print(btree)
measure('resolve')
print(btree.height)
print(WrisbtRoot.empty(128).index(dr, HashPoint.of(btree), WrisbtRoot.empty(128)).height)
measure('index')
def main2():
dr = DumbResolver()
chain: ChainCollectionInterface[Any, Plain, Array[WrisbtRoot]] = BlockChainFactory(
WrisbtChainProtocol(dr, Plain.factory(), 2).loose()
).loose().empty().loose()
for _ in range(1000):
chain = chain.add(HashPoint.of(Plain(os.urandom(16))))
assert chain
# noinspection PyUnresolvedReferences
print(dr.resolve(chain.actual_state().reference.value).height)
def main():
dr = DumbResolver()
tree: ActiveBinaryTree[Plain, Integer] = ActiveBinaryTree.empty(
AVLBTBP(PlainComparator(dr, Replace())), Plain.factory()
)
for i in range(26):
tree = tree.add(HashPoint.of(Plain(bytes([ord('A') + i]))))
print(tree.reference.str(dr, 0))
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -0,0 +1,232 @@
from typing import Generic, TypeVar
from rainbowadn.chain.block import Block, BlockFactory
from rainbowadn.chain.blockchainprotocol import BlockChainProtocol
from rainbowadn.chain.chaincollectionfactory import ChainCollectionFactory
from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.nullability.notnull import NotNull
from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.nullability.nullablereference import NullableReference
from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('BlockChain', 'BlockChainFactory',)
HeaderType = TypeVar('HeaderType')
StateType = TypeVar('StateType')
ActualStateType = TypeVar('ActualStateType')
class BlockChain(
ChainCollectionInterface[
Block[
HeaderType,
StateType
],
HeaderType,
ActualStateType
],
Generic[HeaderType, StateType, ActualStateType],
):
def __init__(
self,
reference: NullableReference[
Block[
HeaderType,
StateType
]
],
protocol: BlockChainProtocol[HeaderType, StateType, ActualStateType],
):
assert isinstance(reference, NullableReference)
assert isinstance(protocol, BlockChainProtocol)
super().__init__(reference, protocol.resolver)
self.protocol = protocol
def factory(self) -> ChainCollectionFactory[
Block[
HeaderType,
StateType
],
HeaderType,
ActualStateType
]:
return BlockChainFactory(self.protocol)
def add(
self,
header: HashPoint[HeaderType]
) -> ChainCollectionInterface[
Block[
HeaderType,
StateType
],
HeaderType,
ActualStateType
]:
assert isinstance(header, HashPoint)
return self.factory().from_reference(
NullableReference.off(
self._add(header)
)
)
def state(
self
) -> NullableReference[
StateType
]:
if isinstance(self.reference.reference, Null):
return NullableReference(
Null(),
self.protocol.state_factory
)
elif isinstance(self.reference.reference, NotNull):
block: Block[
HeaderType,
StateType
] = self.resolver.resolve(self.reference.reference.value)
assert isinstance(block, Block)
return NullableReference.of(block.state)
else:
raise TypeError
def _add(
self,
header: HashPoint[HeaderType]
) -> Block[
HeaderType,
StateType
]:
assert isinstance(header, HashPoint)
return Block(
self.reference,
header,
self.protocol.state_protocol.derive(
self.state(),
header,
)
)
def previous(
self
) -> ChainCollectionInterface[
Block[
HeaderType,
StateType
],
HeaderType,
ActualStateType
]:
assert isinstance(self.reference.reference, NotNull)
block: Block[
HeaderType,
StateType
] = self.resolver.resolve(self.reference.reference.value)
assert isinstance(block, Block)
return self.factory().from_reference(block.previous)
def verify(self) -> bool:
if isinstance(self.reference.reference, Null):
return True
elif isinstance(self.reference.reference, NotNull):
return self.verify_link(
self.previous().reference
) and self.previous().verify()
else:
raise TypeError
def _verify_link(
self,
block: Block[
HeaderType,
StateType
],
previous: NullableReference[
Block[
HeaderType,
StateType
]
]
) -> bool:
assert isinstance(block, Block)
assert isinstance(previous, NullableReference)
assert block.previous == previous
previous_chain = self.factory().from_reference(previous)
assert isinstance(previous_chain, BlockChain)
return self.protocol.state_protocol.verify(
previous_chain.state(),
block.header,
block.state,
)
def _actual_state_factory(self) -> RainbowFactory[ActualStateType]:
return self.protocol.actual_state_factory()
def _actual_state(
self,
block: Block[
HeaderType,
StateType
]
) -> HashPoint[ActualStateType]:
assert isinstance(block, Block)
return self.protocol.actual_state(self.resolver.resolve(block.state))
def loose(self) -> ChainCollectionInterface[
Block[
HeaderType,
StateType
],
HeaderType,
ActualStateType
]:
return self
class BlockChainFactory(
ChainCollectionFactory[
Block[
HeaderType,
StateType
],
HeaderType,
ActualStateType
],
Generic[HeaderType, StateType, ActualStateType]
):
def __init__(
self,
protocol: BlockChainProtocol[HeaderType, StateType, ActualStateType],
):
assert isinstance(protocol, BlockChainProtocol)
self.protocol = protocol
def empty(self) -> BlockChain[HeaderType, StateType, ActualStateType]:
return BlockChain(
NullableReference(
Null(),
BlockFactory(
self.protocol.header_factory,
self.protocol.state_factory
)
),
self.protocol
)
def from_reference(
self,
reference: NullableReference[
Block[
HeaderType,
StateType
],
]
) -> BlockChain[
HeaderType, StateType, ActualStateType
]:
assert isinstance(reference, NullableReference)
return BlockChain(
reference,
self.protocol
)

View File

@ -0,0 +1,43 @@
from typing import Generic, TypeVar
from rainbowadn.chain.states.activestateprotocol import ActiveStateProtocol
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('BlockChainProtocol',)
HeaderType = TypeVar('HeaderType')
StateType = TypeVar('StateType')
ActualStateType = TypeVar('ActualStateType')
class BlockChainProtocol(
Generic[HeaderType, StateType, ActualStateType],
):
def __init__(
self,
protocol: ActiveStateProtocol[HeaderType, StateType],
header_factory: RainbowFactory[StateType],
state_factory: RainbowFactory[StateType]
):
assert isinstance(protocol, ActiveStateProtocol)
assert isinstance(header_factory, RainbowFactory)
assert isinstance(state_factory, RainbowFactory)
self.state_protocol = protocol
self.header_factory = header_factory
self.state_factory = state_factory
self.resolver = protocol.resolver
assert isinstance(self.resolver, HashResolver)
def actual_state_factory(self) -> RainbowFactory[ActualStateType]:
raise NotImplementedError
def actual_state(
self,
state: StateType
) -> HashPoint[ActualStateType]:
raise NotImplementedError
def loose(self) -> 'BlockChainProtocol[HeaderType, StateType, ActualStateType]':
return self

View File

@ -53,17 +53,17 @@ class BlockCollectionInterface(
else: else:
raise TypeError raise TypeError
def _base_state_factory(self) -> RainbowFactory[ActualStateType]: def _actual_state_factory(self) -> RainbowFactory[ActualStateType]:
raise NotImplementedError raise NotImplementedError
def _base_state(self, block: BlockType) -> HashPoint[ActualStateType]: def _actual_state(self, block: BlockType) -> HashPoint[ActualStateType]:
raise NotImplementedError raise NotImplementedError
def base_state(self) -> NullableReference[ActualStateType]: def actual_state(self) -> NullableReference[ActualStateType]:
if isinstance(self.reference.reference, Null): if isinstance(self.reference.reference, Null):
return NullableReference(Null(), self._base_state_factory()) return NullableReference(Null(), self._actual_state_factory())
elif isinstance(self.reference.reference, NotNull): elif isinstance(self.reference.reference, NotNull):
return NullableReference.of(self._base_state(self.resolver.resolve(self.reference.reference.value))) return NullableReference.of(self._actual_state(self.resolver.resolve(self.reference.reference.value)))
else: else:
raise TypeError raise TypeError

View File

@ -19,3 +19,6 @@ class ChainCollectionFactory(Generic[BlockType, HeaderType, ActualStateType]):
reference: NullableReference[BlockType] reference: NullableReference[BlockType]
) -> ChainCollectionInterface[BlockType, HeaderType, ActualStateType]: ) -> ChainCollectionInterface[BlockType, HeaderType, ActualStateType]:
raise NotImplementedError raise NotImplementedError
def loose(self) -> 'ChainCollectionFactory[BlockType, HeaderType, ActualStateType]':
return self

View File

@ -1,306 +0,0 @@
from typing import Generic, TypeVar
from rainbowadn.chain.block import Block, BlockFactory
from rainbowadn.chain.blockcollectioninterface import BlockCollectionInterface
from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface
from rainbowadn.chain.reduction.reduction import Reduction, ReductionFactory
from rainbowadn.chain.reduction.reductionprotocol import ReductionProtocol
from rainbowadn.chain.reduction.reductionstageprotocol import ReductionStageProtocol
from rainbowadn.chain.stages.stage import StageStageFactory, StateStage, StateStageFactory
from rainbowadn.chain.stages.stageprotocol import StageProtocol
from rainbowadn.chain.stages.stagestateprotocol import StageStateProtocol
from rainbowadn.chain.states.stateprotocol import StateProtocol
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.nullability.notnull import NotNull
from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.nullability.nullablereference import NullableReference
from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('ReductionChain',)
ReductorType = TypeVar('ReductorType')
AccumulatorType = TypeVar('AccumulatorType')
class ReductionChain(
ChainCollectionInterface[
Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
],
ReductorType,
AccumulatorType
],
Generic[ReductorType, AccumulatorType]
):
def _verify_link(
self,
block: Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
],
previous: NullableReference[
Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
]
]
) -> bool:
assert isinstance(block, Block)
assert isinstance(previous, NullableReference)
assert block.previous == previous
previous_chain = ReductionChain(previous, self.reductor_factory, self.accumulator_factory, self.protocol)
assert isinstance(previous_chain, BlockCollectionInterface)
state_protocol = StageStateProtocol(self.resolver)
assert isinstance(state_protocol, StateProtocol)
return state_protocol.verify(
previous_chain.state(),
block.header,
block.state,
)
def _base_state_factory(self) -> RainbowFactory[AccumulatorType]:
return self.accumulator_factory
def _base_state(
self,
block: Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
]
) -> HashPoint[AccumulatorType]:
assert isinstance(block, Block)
return self.resolver.resolve(block.state).state
def add(
self,
header: HashPoint[ReductorType]
) -> 'ReductionChain[ReductorType, AccumulatorType]':
assert isinstance(header, HashPoint)
return ReductionChain(
NullableReference.off(
self._add(header)
),
header.factory,
self.accumulator_factory,
self.protocol
)
def __init__(
self,
reference: NullableReference[
Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
]
],
reductor_factory: RainbowFactory[ReductorType],
accumulator_factory: RainbowFactory[AccumulatorType],
protocol: ReductionProtocol[ReductorType, AccumulatorType]
):
assert isinstance(reference, NullableReference)
assert isinstance(reductor_factory, RainbowFactory)
assert isinstance(accumulator_factory, RainbowFactory)
assert isinstance(protocol, ReductionProtocol)
super().__init__(reference, protocol.resolver)
self.reductor_factory = reductor_factory
self.accumulator_factory = accumulator_factory
self.protocol = protocol
@classmethod
def _state_stage_factory(
cls,
reductor_factory: RainbowFactory[ReductorType],
accumulator_factory: RainbowFactory[AccumulatorType],
protocol: ReductionProtocol[ReductorType, AccumulatorType]
) -> RainbowFactory[
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
]:
assert isinstance(reductor_factory, RainbowFactory)
assert isinstance(accumulator_factory, RainbowFactory)
assert isinstance(protocol, ReductionProtocol)
stage_protocol = ReductionStageProtocol(protocol)
assert isinstance(stage_protocol, StageProtocol)
return StateStageFactory(
stage_protocol,
StageStageFactory(
stage_protocol,
ReductionFactory(
reductor_factory,
accumulator_factory
)
),
accumulator_factory
)
@classmethod
def _block_factory(
cls,
reductor_factory: RainbowFactory[ReductorType],
accumulator_factory: RainbowFactory[AccumulatorType],
protocol: ReductionProtocol[ReductorType, AccumulatorType]
) -> RainbowFactory[
Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
]
]:
assert isinstance(reductor_factory, RainbowFactory)
assert isinstance(accumulator_factory, RainbowFactory)
assert isinstance(protocol, ReductionProtocol)
return BlockFactory(
reductor_factory,
cls._state_stage_factory(
reductor_factory,
accumulator_factory,
protocol
)
)
@classmethod
def empty(
cls,
reductor_factory: RainbowFactory[ReductorType],
accumulator_factory: RainbowFactory[AccumulatorType],
protocol: ReductionProtocol[ReductorType, AccumulatorType]
) -> 'ReductionChain[ReductorType, AccumulatorType]':
assert isinstance(reductor_factory, RainbowFactory)
assert isinstance(accumulator_factory, RainbowFactory)
assert isinstance(protocol, ReductionProtocol)
return cls(
NullableReference(
Null(),
cls._block_factory(
reductor_factory,
accumulator_factory,
protocol
)
),
reductor_factory,
accumulator_factory,
protocol
)
def state(
self
) -> NullableReference[
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
]:
if isinstance(self.reference.reference, Null):
return NullableReference(
Null(),
self._state_stage_factory(
self.reductor_factory,
self.accumulator_factory,
self.protocol
)
)
elif isinstance(self.reference.reference, NotNull):
block: Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
] = self.resolver.resolve(self.reference.reference.value)
assert isinstance(block, Block)
return NullableReference.of(block.state)
else:
raise TypeError
def _add(
self,
reductor: HashPoint[ReductorType]
) -> Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
]:
assert isinstance(reductor, HashPoint)
stage_protocol = ReductionStageProtocol(self.protocol)
assert isinstance(stage_protocol, StageProtocol)
return Block(
self.reference,
reductor,
stage_protocol.derive_full(
self.state(),
reductor,
self.accumulator_factory,
ReductionFactory(reductor.factory, self.accumulator_factory)
)
)
def previous(
self
):
assert isinstance(self.reference.reference, NotNull)
block: Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
] = self.resolver.resolve(self.reference.reference.value)
assert isinstance(block, Block)
return ReductionChain(block.previous, self.reductor_factory, self.accumulator_factory, self.protocol)
def verify(self) -> bool:
if isinstance(self.reference.reference, Null):
return True
elif isinstance(self.reference.reference, NotNull):
return self.verify_link(
self.previous().reference
) and self.previous().verify()
else:
raise TypeError
def loose(self) -> ChainCollectionInterface[
Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
],
ReductorType,
AccumulatorType
]:
return self

View File

@ -1,73 +0,0 @@
from typing import Generic, TypeVar
from rainbowadn.chain.block import Block
from rainbowadn.chain.chaincollectionfactory import ChainCollectionFactory
from rainbowadn.chain.reduction.reduction import Reduction
from rainbowadn.chain.reduction.reductionchain import ReductionChain
from rainbowadn.chain.reduction.reductionprotocol import ReductionProtocol
from rainbowadn.chain.stages.stage import StateStage
from rainbowadn.hashing.nullability.nullablereference import NullableReference
from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('ReductionChainFactory',)
ReductorType = TypeVar('ReductorType')
AccumulatorType = TypeVar('AccumulatorType')
class ReductionChainFactory(
ChainCollectionFactory[
Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
],
ReductorType,
AccumulatorType
],
Generic[ReductorType, AccumulatorType]
):
def __init__(
self,
reductor_factory: RainbowFactory[ReductorType],
accumulator_factory: RainbowFactory[AccumulatorType],
protocol: ReductionProtocol[ReductorType, AccumulatorType],
):
assert isinstance(reductor_factory, RainbowFactory)
assert isinstance(accumulator_factory, RainbowFactory)
assert isinstance(protocol, ReductionProtocol)
self.reductor_factory = reductor_factory
self.accumulator_factory = accumulator_factory
self.protocol = protocol
def empty(self) -> ReductionChain[ReductorType, AccumulatorType]:
return ReductionChain.empty(
self.reductor_factory,
self.accumulator_factory,
self.protocol,
)
def from_reference(
self, reference: NullableReference[
Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
],
]
) -> ReductionChain[
ReductorType, AccumulatorType
]:
assert isinstance(reference, NullableReference)
return ReductionChain(
reference,
self.reductor_factory,
self.accumulator_factory,
self.protocol,
)

View File

@ -2,8 +2,10 @@ from typing import Generic, TypeVar
from rainbowadn.chain.abstractreductionchainmetafactory import AbstractReductionChainMetaFactory from rainbowadn.chain.abstractreductionchainmetafactory import AbstractReductionChainMetaFactory
from rainbowadn.chain.block import Block from rainbowadn.chain.block import Block
from rainbowadn.chain.blockchain import BlockChainFactory
from rainbowadn.chain.chaincollectionfactory import ChainCollectionFactory
from rainbowadn.chain.reduction.reduction import Reduction from rainbowadn.chain.reduction.reduction import Reduction
from rainbowadn.chain.reduction.reductionchainfactory import ReductionChainFactory from rainbowadn.chain.reduction.reductionchainprotocol import ReductionChainProtocol
from rainbowadn.chain.reduction.reductionprotocol import ReductionProtocol from rainbowadn.chain.reduction.reductionprotocol import ReductionProtocol
from rainbowadn.chain.stages.stage import StateStage from rainbowadn.chain.stages.stage import StateStage
from rainbowadn.hashing.rainbow_factory import RainbowFactory from rainbowadn.hashing.rainbow_factory import RainbowFactory
@ -34,9 +36,25 @@ class ReductionChainMetaFactory(
reductor_factory: RainbowFactory[ReductorType], reductor_factory: RainbowFactory[ReductorType],
accumulator_factory: RainbowFactory[AccumulatorType], accumulator_factory: RainbowFactory[AccumulatorType],
protocol: ReductionProtocol[ReductorType, AccumulatorType], protocol: ReductionProtocol[ReductorType, AccumulatorType],
): ) -> ChainCollectionFactory[
return ReductionChainFactory( Block[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
],
ReductorType,
AccumulatorType
]:
assert isinstance(reductor_factory, RainbowFactory)
assert isinstance(accumulator_factory, RainbowFactory)
assert isinstance(protocol, ReductionProtocol)
return BlockChainFactory(
ReductionChainProtocol(
protocol,
reductor_factory, reductor_factory,
accumulator_factory, accumulator_factory,
protocol, )
) )

View File

@ -0,0 +1,82 @@
from typing import TypeVar
from rainbowadn.chain.blockchainprotocol import BlockChainProtocol
from rainbowadn.chain.reduction.reduction import Reduction, ReductionFactory
from rainbowadn.chain.reduction.reductionprotocol import ReductionProtocol
from rainbowadn.chain.reduction.reductionstageprotocol import ReductionStageProtocol
from rainbowadn.chain.stages.derivation.activestageprotocol import ActiveStageProtocol
from rainbowadn.chain.stages.derivation.activestagestateprotocol import ActiveStageStateProtocol
from rainbowadn.chain.stages.stage import StateStage, StateStageFactory
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('ReductionChainProtocol',)
ReductorType = TypeVar('ReductorType')
AccumulatorType = TypeVar('AccumulatorType')
class ReductionChainProtocol(
BlockChainProtocol[
ReductorType,
StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
],
AccumulatorType
]
):
def __init__(
self,
protocol: ReductionProtocol[ReductorType, AccumulatorType],
reductor_factory: RainbowFactory[ReductorType],
accumulator_factory: RainbowFactory[AccumulatorType],
):
assert isinstance(protocol, ReductionProtocol)
assert isinstance(reductor_factory, RainbowFactory)
assert isinstance(accumulator_factory, RainbowFactory)
reduction_factory: RainbowFactory[
Reduction[ReductorType, AccumulatorType]
] = ReductionFactory(
reductor_factory, accumulator_factory
)
assert isinstance(reduction_factory, RainbowFactory)
stage_protocol: ActiveStageProtocol[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
] = ReductionStageProtocol(protocol)
assert isinstance(stage_protocol, ActiveStageProtocol)
super().__init__(
ActiveStageStateProtocol(
stage_protocol,
reduction_factory,
accumulator_factory,
),
reductor_factory,
StateStageFactory(
stage_protocol,
reduction_factory,
accumulator_factory
)
)
self.reductor_factory = reductor_factory
self.accumulator_factory = accumulator_factory
def actual_state_factory(self) -> RainbowFactory[AccumulatorType]:
return self.accumulator_factory
def actual_state(
self,
state: StateStage[
ReductorType,
AccumulatorType,
Reduction[ReductorType, AccumulatorType]
]
) -> HashPoint[AccumulatorType]:
assert isinstance(state, StateStage)
return state.state

View File

@ -56,8 +56,10 @@ class ActiveStageProtocol(
def _derive_cycle( def _derive_cycle(
self, self,
stage: StageStage[HeaderType, BaseStateType, StageType], stage: StageStage[HeaderType, BaseStateType, StageType],
stage_factory: RainbowFactory[StageType]
) -> HashPoint[StateStage[HeaderType, BaseStateType, StageType]]: ) -> HashPoint[StateStage[HeaderType, BaseStateType, StageType]]:
assert isinstance(stage, StageStage) assert isinstance(stage, StageStage)
assert isinstance(stage_factory, RainbowFactory)
while True: while True:
derived = self.derive_stage_or_state(stage.stage) derived = self.derive_stage_or_state(stage.stage)
assert isinstance(derived, Derived) assert isinstance(derived, Derived)
@ -65,7 +67,7 @@ class ActiveStageProtocol(
stage = StageStage(self, NullableReference.off(stage), derived.stage) stage = StageStage(self, NullableReference.off(stage), derived.stage)
assert isinstance(stage, StageStage) assert isinstance(stage, StageStage)
elif isinstance(derived, DerivedState): elif isinstance(derived, DerivedState):
return HashPoint.of(StateStage(self, HashPoint.of(stage), derived.state)) return HashPoint.of(StateStage(self, HashPoint.of(stage), derived.state, stage_factory))
else: else:
raise TypeError raise TypeError
@ -109,7 +111,8 @@ class ActiveStageProtocol(
), ),
header, header,
stage_factory stage_factory
) ),
stage_factory
) )
def verify_header( def verify_header(

View File

@ -0,0 +1,91 @@
from typing import TypeVar
from rainbowadn.chain.stages.derivation.activestageprotocol import ActiveStageProtocol
from rainbowadn.chain.stages.stage import StateStage
from rainbowadn.chain.states.activestateprotocol import ActiveStateProtocol
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.nullability.nullablereference import NullableReference
from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('ActiveStageStateProtocol',)
HeaderType = TypeVar('HeaderType')
BaseStateType = TypeVar('BaseStateType')
StageType = TypeVar('StageType')
class ActiveStageStateProtocol(
ActiveStateProtocol[
HeaderType,
StateStage[
HeaderType,
BaseStateType,
StageType
]
]
):
def __init__(
self,
protocol: ActiveStageProtocol,
stage_factory: RainbowFactory[StageType],
base_state_factory: RainbowFactory[BaseStateType],
):
assert isinstance(protocol, ActiveStageProtocol)
assert isinstance(stage_factory, RainbowFactory)
assert isinstance(base_state_factory, RainbowFactory)
super().__init__(protocol.resolver)
self.protocol = protocol
self.stage_factory = stage_factory
self.base_state_factory = base_state_factory
def _initial_state(self) -> HashPoint[
StateStage[
HeaderType,
BaseStateType,
StageType
]
]:
raise TypeError('use .derive()')
def _derive(
self,
previous: HashPoint[StateStage[
HeaderType,
BaseStateType,
StageType
]],
header: HashPoint[HeaderType]
) -> HashPoint[
StateStage[
HeaderType,
BaseStateType,
StageType
]
]:
raise TypeError('use .derive()')
def derive(
self,
previous: NullableReference[
StateStage[
HeaderType,
BaseStateType,
StageType
]
],
header: HashPoint[HeaderType],
) -> HashPoint[
StateStage[
HeaderType,
BaseStateType,
StageType
]
]:
assert isinstance(previous, NullableReference)
assert isinstance(header, HashPoint)
return self.protocol.derive_full(
previous,
header,
self.base_state_factory,
self.stage_factory
)

View File

@ -143,14 +143,17 @@ class StateStage(
self, self,
protocol: StageProtocol[HeaderType, BaseStateType, StageType], protocol: StageProtocol[HeaderType, BaseStateType, StageType],
previous: HashPoint[StageStage[HeaderType, BaseStateType, StageType]], previous: HashPoint[StageStage[HeaderType, BaseStateType, StageType]],
state: HashPoint[BaseStateType] state: HashPoint[BaseStateType],
stage_factory: RainbowFactory[StageType]
): ):
assert isinstance(protocol, StageProtocol) assert isinstance(protocol, StageProtocol)
assert isinstance(previous, HashPoint) assert isinstance(previous, HashPoint)
assert isinstance(state, HashPoint) assert isinstance(state, HashPoint)
assert isinstance(stage_factory, RainbowFactory)
super().__init__(protocol) super().__init__(protocol)
self.previous = previous self.previous = previous
self.state = state self.state = state
self.stage_factory = stage_factory
def verify( def verify(
self, self,
@ -181,7 +184,7 @@ class StateStage(
def __factory__(self) -> RainbowFactory['StateStage[HeaderType, BaseStateType, StageType]']: def __factory__(self) -> RainbowFactory['StateStage[HeaderType, BaseStateType, StageType]']:
return StateStageFactory( return StateStageFactory(
self.protocol, self.protocol,
self.previous.factory, self.stage_factory,
self.state.factory self.state.factory
) )
@ -196,20 +199,27 @@ class StateStageFactory(RainbowFactory[StateStage[HeaderType, BaseStateType, Sta
def __init__( def __init__(
self, self,
protocol: StageProtocol[HeaderType, BaseStateType, StageType], protocol: StageProtocol[HeaderType, BaseStateType, StageType],
stage_stage_factory: RainbowFactory[StageStage[HeaderType, BaseStateType, StageType]], stage_factory: RainbowFactory[StageType],
state_factory: RainbowFactory[BaseStateType] state_factory: RainbowFactory[BaseStateType]
): ):
assert isinstance(protocol, StageProtocol) assert isinstance(protocol, StageProtocol)
assert isinstance(stage_stage_factory, RainbowFactory) assert isinstance(stage_factory, RainbowFactory)
assert isinstance(state_factory, RainbowFactory) assert isinstance(state_factory, RainbowFactory)
self.protocol = protocol self.protocol = protocol
self.stage_stage_factory = stage_stage_factory self.stage_factory = stage_factory
self.state_factory = state_factory self.state_factory = state_factory
def from_bytes(self, source: bytes) -> StateStage[HeaderType, BaseStateType, StageType]: def from_bytes(self, source: bytes) -> StateStage[HeaderType, BaseStateType, StageType]:
assert isinstance(source, bytes) assert isinstance(source, bytes)
return StateStage( return StateStage(
self.protocol, self.protocol,
HashPoint(self.stage_stage_factory, source[:HashPoint.HASH_LENGTH], Null()), HashPoint(
StageStageFactory(
self.protocol,
self.stage_factory
),
source[:HashPoint.HASH_LENGTH], Null()
),
HashPoint(self.state_factory, source[HashPoint.HASH_LENGTH:], Null()), HashPoint(self.state_factory, source[HashPoint.HASH_LENGTH:], Null()),
self.stage_factory
) )

View File

@ -0,0 +1,52 @@
from typing import TypeVar
from rainbowadn.chain.states.stateprotocol import StateProtocol
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.nullability.notnull import NotNull
from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.nullability.nullablereference import NullableReference
__all__ = ('ActiveStateProtocol',)
HeaderType = TypeVar('HeaderType')
StateType = TypeVar('StateType')
class ActiveStateProtocol(StateProtocol[HeaderType, StateType]):
def verify(
self,
previous: NullableReference[StateType],
header: HashPoint[HeaderType],
state: HashPoint[StateType]
) -> bool:
assert isinstance(previous, NullableReference)
assert isinstance(header, HashPoint)
assert isinstance(state, HashPoint)
assert state == self.derive(previous, header)
return True
def _initial_state(self) -> HashPoint[StateType]:
raise NotImplementedError
def _derive(
self,
previous: HashPoint[StateType],
header: HashPoint[HeaderType],
) -> HashPoint[StateType]:
raise NotImplementedError
def derive(
self,
previous: NullableReference[StateType],
header: HashPoint[HeaderType],
) -> HashPoint[StateType]:
assert isinstance(previous, NullableReference)
assert isinstance(header, HashPoint)
if isinstance(previous.reference, Null):
previous_state: HashPoint[StateType] = self._initial_state()
elif isinstance(previous.reference, NotNull):
previous_state: HashPoint[StateType] = previous.reference.value
else:
raise TypeError
assert isinstance(previous_state, HashPoint)
return self._derive(previous_state, header)

View File

@ -19,6 +19,6 @@ class StateProtocol(Generic[HeaderType, StateType]):
self, self,
previous: NullableReference[StateType], previous: NullableReference[StateType],
header: HashPoint[HeaderType], header: HashPoint[HeaderType],
state: NullableReference[StateType] state: HashPoint[StateType]
) -> bool: ) -> bool:
raise NotImplementedError raise NotImplementedError

View File

@ -1,5 +1,5 @@
import abc import abc
from typing import Generic, TypeVar from typing import TypeVar
from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.static import StaticMentionable from rainbowadn.hashing.static import StaticMentionable
@ -9,6 +9,6 @@ __all__ = ('Atomic',)
AtomicMentioned = TypeVar('AtomicMentioned') AtomicMentioned = TypeVar('AtomicMentioned')
class Atomic(StaticMentionable[AtomicMentioned], abc.ABC, Generic[AtomicMentioned]): class Atomic(StaticMentionable, abc.ABC):
def __topology_hash__(self) -> bytes: def __topology_hash__(self) -> bytes:
return HashPoint.NULL_HASH return HashPoint.hash(b'')

View File

@ -3,7 +3,7 @@ from rainbowadn.data.atomic.atomic import Atomic
__all__ = ('Integer',) __all__ = ('Integer',)
class Integer(Atomic['Integer']): class Integer(Atomic):
def __init__(self, integer: int): def __init__(self, integer: int):
assert isinstance(integer, int) assert isinstance(integer, int)
assert integer >= 0 assert integer >= 0

View File

@ -3,7 +3,7 @@ from rainbowadn.data.atomic.atomic import Atomic
__all__ = ('Plain',) __all__ = ('Plain',)
class Plain(Atomic['Plain']): class Plain(Atomic):
def __init__(self, source: bytes): def __init__(self, source: bytes):
assert isinstance(source, bytes) assert isinstance(source, bytes)
self.source = source self.source = source

View File

@ -0,0 +1,64 @@
from typing import Generic, Iterable, TypeVar
from rainbowadn.hashing.hash_point_format import hash_point_format, tabulate
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.rainbow_factory import RainbowFactory
from rainbowadn.hashing.recursivementionable import RecursiveMentionable
__all__ = ('Array', 'ArrayFactory',)
ElementType = TypeVar('ElementType')
class Array(RecursiveMentionable, Generic[ElementType]):
def __init__(
self,
factory: RainbowFactory[ElementType],
array: tuple[HashPoint[ElementType], ...]
):
assert isinstance(factory, RainbowFactory)
assert isinstance(array, tuple)
self.factory = factory
self.array = array
def points(self) -> Iterable[HashPoint]:
return self.array
def __bytes__(self):
return b''.join(map(HashPoint.__bytes__, self.array))
def __factory__(self) -> RainbowFactory['Array']:
return ArrayFactory(self.factory)
def str(self, resolver: HashResolver, tab: int) -> str:
assert isinstance(resolver, HashResolver)
assert isinstance(tab, int)
formatted = f'('
for hash_point in self.array:
formatted += f'{tabulate(tab+1)}{hash_point_format(hash_point,resolver,tab+1)}'
return f'{formatted}' \
f'{tabulate(tab)})'
class ArrayFactory(RainbowFactory[Array], Generic[ElementType]):
def __init__(
self,
factory: RainbowFactory[ElementType]
):
assert isinstance(factory, RainbowFactory)
self.factory = factory
def from_bytes(self, source: bytes) -> Array:
assert isinstance(source, bytes)
return Array(
self.factory,
tuple(
HashPoint(self.factory, source[i:i + HashPoint.HASH_LENGTH], Null())
for
i
in
range(0, len(source), HashPoint.HASH_LENGTH)
)
)

View File

@ -1,40 +0,0 @@
from typing import Generic, TypeVar
from rainbowadn.data.collection.collection_interface.activecollectioninterface import ActiveCollectionInterface
from rainbowadn.data.collection.stack.stack import Stack
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
from rainbowadn.hashing.nullability.notnull import NotNull
from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.nullability.nullablereference import NullableReference
from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('ActiveStack',)
ElementType = TypeVar('ElementType')
class ActiveStack(ActiveCollectionInterface[Stack[ElementType], ElementType], Generic[ElementType]):
def __init__(self, reference: NullableReference[Stack[ElementType]]):
assert isinstance(reference, NullableReference)
super().__init__(reference)
def add(self, element: HashPoint[ElementType]) -> 'ActiveStack[ElementType]':
assert isinstance(element, HashPoint)
return ActiveStack(NullableReference.off(Stack(self.reference, element)))
@classmethod
def empty(cls, factory: RainbowFactory[ElementType]) -> 'ActiveStack[ElementType]':
assert isinstance(factory, RainbowFactory)
return cls(NullableReference(Null(), Stack.factory(factory)))
def str(self, resolver: HashResolver):
assert isinstance(resolver, HashResolver)
if isinstance(self.reference.reference, Null):
return f'-'
elif isinstance(self.reference.reference, NotNull):
stack: Stack[ElementType] = resolver.resolve(self.reference.reference.value)
assert isinstance(stack, Stack)
return f'{ActiveStack(stack.previous).str(resolver)} {resolver.resolve(stack.element)}'
else:
raise TypeError

View File

@ -50,9 +50,11 @@ class Stack(RecursiveMentionable, Generic[ElementType]):
]: ]:
assert isinstance(factory, RainbowFactory) assert isinstance(factory, RainbowFactory)
reference: NullableReference[Stack[ElementType]] = NullableReference(Null(), cls.factory(factory)) reference: NullableReference[Stack[ElementType]] = NullableReference(Null(), cls.factory(factory))
assert isinstance(reference, NullableReference)
for element in elements: for element in elements:
assert isinstance(element, HashPoint) assert isinstance(element, HashPoint)
reference = NullableReference.off(cls(reference, element)) reference = NullableReference.off(cls(reference, element))
assert isinstance(reference, NullableReference)
return reference return reference
@classmethod @classmethod
@ -63,6 +65,7 @@ class Stack(RecursiveMentionable, Generic[ElementType]):
) -> NullableReference[ ) -> NullableReference[
'Stack[ElementType]' 'Stack[ElementType]'
]: ]:
assert isinstance(factory, RainbowFactory)
return cls.of(factory, map(HashPoint.of, elements)) return cls.of(factory, map(HashPoint.of, elements))

View File

@ -1,19 +1,22 @@
from typing import Generic, TypeVar from typing import Generic, TypeVar
from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree
from rainbowadn.data.collection.trees.comparison.comparator import (Comparator, Comparison, Left, Replace, Right)
from rainbowadn.data.collection.trees.comparison.keyedcomparator import KeyedComparator
from rainbowadn.data.collection.trees.binary.querybinarytree import QueryBinaryTree
from rainbowadn.data.collection.collection_interface.activecollectioninterface import ActiveCollectionInterface from rainbowadn.data.collection.collection_interface.activecollectioninterface import ActiveCollectionInterface
from rainbowadn.data.collection.collection_interface.querycollectioninterface import QueryCollectionInterface from rainbowadn.data.collection.collection_interface.querycollectioninterface import QueryCollectionInterface
from rainbowadn.data.collection.keymetadata import KeyMetadata from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory
from rainbowadn.data.collection.keymetadataquerycollection import KeyMetadataQueryCollection from rainbowadn.data.collection.keymetadataquerycollection import KeyMetadataQueryCollection
from rainbowadn.data.collection.trees.binary.balancedtreecreationprotocol import BalancedTreeCreationProtocol
from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, BinaryTreeFactory
from rainbowadn.data.collection.trees.binary.binarytreebalancingprotocol import BinaryTreeBalancingProtocol
from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol
from rainbowadn.data.collection.trees.binary.querybinarytree import QueryBinaryTree
from rainbowadn.data.collection.trees.comparison.comparator import (Comparator, Comparison, Left, Replace, Right)
from rainbowadn.data.collection.trees.comparison.keyedcomparator import KeyedComparator
from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver from rainbowadn.hashing.hashresolver import HashResolver
from rainbowadn.hashing.nullability.notnull import NotNull from rainbowadn.hashing.nullability.notnull import NotNull
from rainbowadn.hashing.nullability.null import Null from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.nullability.nullable import Nullable
from rainbowadn.hashing.nullability.nullablereference import NullableReference from rainbowadn.hashing.nullability.nullablereference import NullableReference
from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('ActiveBinaryTree',) __all__ = ('ActiveBinaryTree',)
@ -27,40 +30,34 @@ class ActiveBinaryTree(
): ):
def __init__( def __init__(
self, self,
comparator: Comparator[ActiveKeyType], protocol: BinaryTreeBalancingProtocol[ActiveKeyType, MetaDataType, 'ActiveBinaryTree'],
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]] reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
): ):
assert isinstance(comparator, Comparator) assert isinstance(protocol, BinaryTreeBalancingProtocol)
assert isinstance(reference, NullableReference) assert isinstance(reference, NullableReference)
super().__init__(reference) super().__init__(reference)
self.comparator = comparator self.protocol = protocol
self.resolver = comparator.resolver self.comparator = protocol.comparator
assert isinstance(self.comparator, Comparator)
self.resolver = protocol.resolver
assert isinstance(self.resolver, HashResolver) assert isinstance(self.resolver, HashResolver)
self.creation = ActiveCreationProtocol(protocol)
assert isinstance(self.creation, BinaryTreeCreationProtocol)
def empty_metadata(self) -> HashPoint[MetaDataType]: @classmethod
raise NotImplementedError def empty(
cls,
def metadata( protocol: BinaryTreeBalancingProtocol[ActiveKeyType, MetaDataType, 'ActiveBinaryTree'],
self, factory: RainbowFactory[ActiveKeyType]
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]], ):
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]], assert isinstance(protocol, BinaryTreeBalancingProtocol)
key: HashPoint[ActiveKeyType] assert isinstance(factory, RainbowFactory)
) -> HashPoint[MetaDataType]: return cls(
raise NotImplementedError protocol,
NullableReference(
def _binary_tree( Null(),
self, BinaryTreeFactory(KeyMetadataFactory(factory, protocol.empty_metadata().factory))
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]], )
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
key: HashPoint[ActiveKeyType]
) -> BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]:
assert isinstance(treel, NullableReference)
assert isinstance(treer, NullableReference)
assert isinstance(key, HashPoint)
return BinaryTree(
treel,
treer,
HashPoint.of(KeyMetadata(key, self.metadata(treel, treer, key)))
) )
def create( def create(
@ -68,81 +65,82 @@ class ActiveBinaryTree(
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]] reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': ) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
assert isinstance(reference, NullableReference) assert isinstance(reference, NullableReference)
return type(self)( return ActiveBinaryTree(
self.comparator, self.protocol,
reference reference
) )
def active_tree(
self,
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
key: HashPoint[ActiveKeyType]
) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
assert isinstance(treel, NullableReference)
assert isinstance(treer, NullableReference)
assert isinstance(key, HashPoint)
return self.create(
NullableReference.off(
self._binary_tree(
self.create(treel).balance().reference,
self.create(treer).balance().reference,
key
)
)
).balance()
def add(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': def add(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
assert isinstance(key, HashPoint) assert isinstance(key, HashPoint)
reference: Nullable[ if self.creation.splittable(self):
HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]] treel: ActiveBinaryTree[ActiveKeyType, MetaDataType]
] = self.reference.reference original: HashPoint[ActiveKeyType]
assert isinstance(reference, Nullable) treer: ActiveBinaryTree[ActiveKeyType, MetaDataType]
if isinstance(reference, Null): treel, original, _, treer = self.creation.split(self)
return self.active_tree(self.reference, self.reference, key) assert isinstance(treel, ActiveBinaryTree)
elif isinstance(reference, NotNull):
tree: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = self.resolver.resolve(reference.value)
assert isinstance(tree, BinaryTree)
original: HashPoint[ActiveKeyType] = self.resolver.resolve(tree.key).key
assert isinstance(original, HashPoint) assert isinstance(original, HashPoint)
assert isinstance(treer, ActiveBinaryTree)
comparison: Comparison = self.comparator.compare(original, key) comparison: Comparison = self.comparator.compare(original, key)
assert isinstance(comparison, Comparison) assert isinstance(comparison, Comparison)
if isinstance(comparison, Replace): if isinstance(comparison, Replace):
return self.active_tree(tree.treel, tree.treer, key) return self.creation.tree(treel, treer, key)
elif isinstance(comparison, Left): elif isinstance(comparison, Left):
return self.active_tree(self.create(tree.treel).add(key).reference, tree.treer, original) return self.creation.tree(treel.add(key), treer, original)
elif isinstance(comparison, Right): elif isinstance(comparison, Right):
return self.active_tree(tree.treel, self.create(tree.treer).add(key).reference, original) return self.creation.tree(treel, treer.add(key), original)
else: else:
raise TypeError raise TypeError
else: else:
raise TypeError return self.creation.tree(self, self, key)
def balance(self) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
raise NotImplementedError
def __str__(self):
reference: Nullable[
HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
] = self.reference.reference
assert isinstance(reference, Nullable)
if isinstance(reference, Null):
return '_'
elif isinstance(reference, NotNull):
tree: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = self.resolver.resolve(reference.value)
assert isinstance(tree, BinaryTree)
key: KeyMetadata[ActiveKeyType, MetaDataType] = self.resolver.resolve(tree.key)
assert isinstance(key, KeyMetadata)
return f'( {self.create(tree.treel)}' \
f' {self.resolver.resolve(key.key)}' \
f' {self.resolver.resolve(key.metadata)}' \
f' {self.create(tree.treer)} )'
else:
raise TypeError
def query_tree(self) -> QueryCollectionInterface[ActiveKeyType]: def query_tree(self) -> QueryCollectionInterface[ActiveKeyType]:
return KeyMetadataQueryCollection( return KeyMetadataQueryCollection(
self.empty_metadata(), self.protocol.empty_metadata(),
QueryBinaryTree(KeyedComparator(self.resolver, self.comparator), self.reference), QueryBinaryTree(KeyedComparator(self.comparator), self.reference),
self.resolver self.resolver
) )
class ActiveCreationProtocol(BalancedTreeCreationProtocol[ActiveKeyType, MetaDataType, ActiveBinaryTree]):
def splittable(self, tree: ActiveBinaryTree[ActiveKeyType, MetaDataType]) -> bool:
assert isinstance(tree, ActiveBinaryTree)
return isinstance(tree.reference.reference, NotNull)
def split(
self,
tree: ActiveBinaryTree[ActiveKeyType, MetaDataType]
) -> tuple[
ActiveBinaryTree[ActiveKeyType, MetaDataType],
HashPoint[ActiveKeyType],
HashPoint[MetaDataType],
ActiveBinaryTree[ActiveKeyType, MetaDataType]
]:
assert isinstance(tree, ActiveBinaryTree)
assert isinstance(tree.reference.reference, NotNull)
hash_point: HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]] = tree.reference.reference.value
assert isinstance(hash_point, HashPoint)
resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = self.resolver.resolve(hash_point)
assert isinstance(resolved, BinaryTree)
key_metadata: KeyMetadata[ActiveKeyType, MetaDataType] = self.resolver.resolve(resolved.key)
assert isinstance(key_metadata, KeyMetadata)
return tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer)
def _tree(
self,
treel: ActiveBinaryTree,
treer: ActiveBinaryTree,
key: HashPoint[ActiveKeyType]
) -> ActiveBinaryTree:
assert isinstance(treel, ActiveBinaryTree)
assert isinstance(treer, ActiveBinaryTree)
assert isinstance(key, HashPoint)
return ActiveBinaryTree(
self.protocol,
NullableReference.off(
BinaryTree(
treel.reference,
treer.reference,
HashPoint.of(KeyMetadata(key, self.protocol.metadata(treel, treer, key, self)))
)
)
)

View File

@ -1,180 +1,86 @@
from typing import Generic, TypeVar from typing import TypeVar
from rainbowadn.data.atomic.integer import Integer from rainbowadn.data.atomic.integer import Integer
from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinaryTree from rainbowadn.data.collection.trees.binary.binarytreebalancingprotocol import BinaryTreeBalancingProtocol
from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, BinaryTreeFactory from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol
from rainbowadn.data.collection.trees.comparison.comparator import Comparator
from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory
from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.nullability.notnull import NotNull
from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.nullability.nullable import Nullable
from rainbowadn.hashing.nullability.nullablereference import NullableReference
from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('AVLABT',) __all__ = ('AVLBTBP',)
ActiveKeyType = TypeVar('ActiveKeyType') ActiveKeyType = TypeVar('ActiveKeyType')
TreeType = TypeVar('TreeType')
class AVLABT(ActiveBinaryTree[ActiveKeyType, Integer], Generic[ActiveKeyType]): class AVLBTBP(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]):
def __init__(
self,
comparator: Comparator[ActiveKeyType],
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]]
):
assert isinstance(comparator, Comparator)
assert isinstance(reference, NullableReference)
super().__init__(comparator, reference)
def create(
self, reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]]
) -> 'AVLABT[ActiveKeyType]':
assert isinstance(reference, NullableReference)
return type(self)(
self.comparator,
reference
)
def height(self) -> int:
reference: Nullable[
HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]]
] = self.reference.reference
assert isinstance(reference, Nullable)
if isinstance(reference, Null):
return 0
elif isinstance(reference, NotNull):
tree: BinaryTree[KeyMetadata[ActiveKeyType, Integer]] = self.resolver.resolve(reference.value)
assert isinstance(tree, BinaryTree)
key: KeyMetadata[ActiveKeyType, Integer] = self.resolver.resolve(tree.key)
assert isinstance(key, KeyMetadata)
return self.resolver.resolve(key.metadata).integer
@classmethod
def empty(
cls,
comparator: Comparator[ActiveKeyType],
factory: RainbowFactory[ActiveKeyType]
):
assert isinstance(comparator, Comparator)
assert isinstance(factory, RainbowFactory)
return cls(
comparator,
NullableReference(
Null(),
BinaryTreeFactory(KeyMetadataFactory(factory, Integer.factory()))
)
)
def empty_metadata(self) -> HashPoint[Integer]: def empty_metadata(self) -> HashPoint[Integer]:
return HashPoint.of(Integer(0)) return HashPoint.of(Integer(0))
def metadata( def metadata(
self, self,
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]], treel: TreeType,
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]], treer: TreeType,
key: HashPoint[ActiveKeyType] key: HashPoint[ActiveKeyType],
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
) -> HashPoint[Integer]: ) -> HashPoint[Integer]:
assert isinstance(treel, NullableReference) return HashPoint.of(
assert isinstance(treer, NullableReference) Integer(1 + max(self.height(treel, protocol), self.height(treer, protocol)))
assert isinstance(key, HashPoint) )
return HashPoint.of(Integer(1 + max(self.create(treel).height(), self.create(treer).height())))
def balance(self) -> ActiveBinaryTree[ActiveKeyType, Integer]: def height(
reference: Nullable[ self,
HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]] tree: TreeType,
] = self.reference.reference protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
assert isinstance(reference, Nullable) ) -> int:
if isinstance(reference, Null): if protocol.splittable(tree):
return self _, _, metadata, _ = protocol.split(tree)
elif isinstance(reference, NotNull): return self.resolver.resolve(metadata).integer
tree: BinaryTree[KeyMetadata[ActiveKeyType, Integer]] = self.resolver.resolve(reference.value) else:
assert isinstance(tree, BinaryTree) return 0
atl = self.create(tree.treel)
assert isinstance(atl, ActiveBinaryTree) def balance(
atr = self.create(tree.treer) self,
assert isinstance(atr, ActiveBinaryTree) tree: TreeType,
delta = atl.height() - atr.height() protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
) -> TreeType:
if protocol.splittable(tree):
treel, key, _, treer = protocol.split(tree)
delta = self.height(treel, protocol) - self.height(treer, protocol)
assert isinstance(delta, int) assert isinstance(delta, int)
if delta < -1: if delta < -1:
assert isinstance(atr.reference.reference, NotNull) assert protocol.splittable(treer)
treer: BinaryTree[ treerl, keyr, _, treerr = protocol.split(treer)
KeyMetadata[ActiveKeyType, Integer] if self.height(treerl, protocol) > self.height(treerr, protocol):
] = self.resolver.resolve(atr.reference.reference.value) assert protocol.splittable(treerl)
assert isinstance(treer, BinaryTree) treerll, keyrl, _, treerlr = protocol.split(treerl)
atrl = self.create(treer.treel) return protocol.tree(
assert isinstance(atrl, ActiveBinaryTree) protocol.tree(treel, treerll, key),
atrr = self.create(treer.treer) protocol.tree(treerlr, treerr, keyr),
assert isinstance(atrr, ActiveBinaryTree) keyrl
if atrl.height() > atrr.height():
assert isinstance(atrl.reference.reference, NotNull)
treerl: BinaryTree[
KeyMetadata[ActiveKeyType, Integer]
] = self.resolver.resolve(atrl.reference.reference.value)
assert isinstance(treerl, BinaryTree)
return self.active_tree(
self.active_tree(
atl.reference,
treerl.treel,
self.resolver.resolve(tree.key).key
).reference,
self.active_tree(
treerl.treer,
atrr.reference,
self.resolver.resolve(treer.key).key
).reference,
self.resolver.resolve(treerl.key).key
) )
else: else:
return self.active_tree( return protocol.tree(
self.active_tree( protocol.tree(treel, treerl, key),
atl.reference, treerr,
atrl.reference, keyr
self.resolver.resolve(tree.key).key
).reference,
atrr.reference,
self.resolver.resolve(treer.key).key
) )
elif delta > 1: elif delta > 1:
assert isinstance(atl.reference.reference, NotNull) assert protocol.splittable(treel)
treel: BinaryTree[ treell, keyl, _, treelr = protocol.split(treel)
KeyMetadata[ActiveKeyType, Integer] if self.height(treelr, protocol) > self.height(treell, protocol):
] = self.resolver.resolve(atl.reference.reference.value) assert protocol.splittable(treelr)
assert isinstance(treel, BinaryTree) treelrl, keylr, _, treelrr = protocol.split(treelr)
atlr = self.create(treel.treer) return protocol.tree(
assert isinstance(atlr, ActiveBinaryTree) protocol.tree(treell, treelrl, keyl),
atll = self.create(treel.treel) protocol.tree(treelrr, treer, key),
assert isinstance(atll, ActiveBinaryTree) keylr
if atlr.height() > atll.height():
assert isinstance(atlr.reference.reference, NotNull)
treelr: BinaryTree[
KeyMetadata[ActiveKeyType, Integer]
] = self.resolver.resolve(atlr.reference.reference.value)
assert isinstance(treelr, BinaryTree)
return self.active_tree(
self.active_tree(
atll.reference,
treelr.treel,
self.resolver.resolve(treel.key).key
).reference,
self.active_tree(
treelr.treer,
atr.reference,
self.resolver.resolve(tree.key).key
).reference,
self.resolver.resolve(treelr.key).key
) )
else: else:
return self.active_tree( return protocol.tree(
atll.reference, treell,
self.active_tree( protocol.tree(treelr, treer, key),
atlr.reference, keyl
atr.reference,
self.resolver.resolve(tree.key).key
).reference,
self.resolver.resolve(treel.key).key
) )
else: else:
return self return tree
else: else:
raise TypeError return tree

View File

@ -0,0 +1,46 @@
from typing import Generic, TypeVar
from rainbowadn.data.collection.trees.binary.binarytreebalancingprotocol import BinaryTreeBalancingProtocol
from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
__all__ = ('BalancedTreeCreationProtocol',)
TreeType = TypeVar('TreeType')
ActiveKeyType = TypeVar('ActiveKeyType')
MetaDataType = TypeVar('MetaDataType')
class BalancedTreeCreationProtocol(
BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
Generic[ActiveKeyType, MetaDataType, TreeType]
):
def __init__(
self,
protocol: BinaryTreeBalancingProtocol[ActiveKeyType, MetaDataType, TreeType]
):
assert isinstance(protocol, BinaryTreeBalancingProtocol)
self.protocol = protocol
self.resolver = protocol.resolver
assert isinstance(self.resolver, HashResolver)
def splittable(self, tree: TreeType) -> bool:
raise NotImplementedError
def split(self, tree: TreeType) -> tuple[TreeType, HashPoint[ActiveKeyType], HashPoint[MetaDataType], TreeType]:
raise NotImplementedError
def _tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
raise NotImplementedError
def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
assert isinstance(key, HashPoint)
return self.protocol.balance(
self._tree(
self.protocol.balance(treel, self),
self.protocol.balance(treer, self),
key
),
self
)

View File

@ -0,0 +1,42 @@
from typing import Generic, TypeVar
from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol
from rainbowadn.data.collection.trees.comparison.comparator import Comparator
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
__all__ = ('BinaryTreeBalancingProtocol',)
TreeType = TypeVar('TreeType')
ActiveKeyType = TypeVar('ActiveKeyType')
MetaDataType = TypeVar('MetaDataType')
class BinaryTreeBalancingProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]):
def __init__(
self,
comparator: Comparator[ActiveKeyType]
):
assert isinstance(comparator, Comparator)
self.comparator = comparator
self.resolver = comparator.resolver
assert isinstance(self.resolver, HashResolver)
def empty_metadata(self) -> HashPoint[MetaDataType]:
raise NotImplementedError
def metadata(
self,
treel: TreeType,
treer: TreeType,
key: HashPoint[ActiveKeyType],
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType]
) -> HashPoint[MetaDataType]:
raise NotImplementedError
def balance(
self,
tree: TreeType,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType]
) -> TreeType:
raise NotImplementedError

View File

@ -0,0 +1,20 @@
from typing import Generic, TypeVar
from rainbowadn.hashing.hashpoint import HashPoint
__all__ = ('BinaryTreeCreationProtocol',)
TreeType = TypeVar('TreeType')
ActiveKeyType = TypeVar('ActiveKeyType')
MetaDataType = TypeVar('MetaDataType')
class BinaryTreeCreationProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]):
def splittable(self, tree: TreeType) -> bool:
raise NotImplementedError
def split(self, tree: TreeType) -> tuple[TreeType, HashPoint[ActiveKeyType], HashPoint[MetaDataType], TreeType]:
raise NotImplementedError
def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
raise NotImplementedError

View File

@ -1,75 +0,0 @@
from typing import Generic, TypeVar
from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinaryTree
from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, BinaryTreeFactory
from rainbowadn.data.collection.trees.comparison.comparator import Comparator
from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.nullability.nullablereference import NullableReference
from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('UnbalancedABT',)
ActiveKeyType = TypeVar('ActiveKeyType')
MetaDataType = TypeVar('MetaDataType')
class UnbalancedABT(ActiveBinaryTree[ActiveKeyType, MetaDataType], Generic[ActiveKeyType, MetaDataType]):
def __init__(
self,
comparator: Comparator[ActiveKeyType],
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
metadata: HashPoint[MetaDataType]
):
assert isinstance(comparator, Comparator)
assert isinstance(reference, NullableReference)
assert isinstance(metadata, HashPoint)
super().__init__(comparator, reference)
self._metadata = metadata
def create(
self, reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
) -> 'UnbalancedABT[ActiveKeyType, MetaDataType]':
assert isinstance(reference, NullableReference)
return type(self)(
self.comparator,
reference,
self._metadata
)
@classmethod
def empty(
cls,
comparator: Comparator[ActiveKeyType],
metadata: HashPoint[MetaDataType],
factory: RainbowFactory[ActiveKeyType]
):
assert isinstance(comparator, Comparator)
assert isinstance(metadata, HashPoint)
assert isinstance(factory, RainbowFactory)
return cls(
comparator,
NullableReference(
Null(),
BinaryTreeFactory(KeyMetadataFactory(factory, metadata.factory))
),
metadata
)
def empty_metadata(self) -> HashPoint[MetaDataType]:
return self._metadata
def metadata(
self,
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
key: HashPoint[ActiveKeyType]
) -> HashPoint[MetaDataType]:
assert isinstance(treel, NullableReference)
assert isinstance(treer, NullableReference)
assert isinstance(key, HashPoint)
return self._metadata
def balance(self) -> 'UnbalancedABT[ActiveKeyType, MetaDataType]':
return self

View File

@ -1,9 +1,8 @@
from typing import Generic, TypeVar from typing import Generic, TypeVar
from rainbowadn.data.collection.trees.comparison.comparator import Comparator, Comparison
from rainbowadn.data.collection.keyed import Keyed from rainbowadn.data.collection.keyed import Keyed
from rainbowadn.data.collection.trees.comparison.comparator import Comparator, Comparison
from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
__all__ = ('KeyedComparator',) __all__ = ('KeyedComparator',)
@ -13,11 +12,10 @@ ComparatorKeyType = TypeVar('ComparatorKeyType')
class KeyedComparator( class KeyedComparator(
Comparator[Keyed[ComparatorKeyType]], Generic[ComparatorKeyType] Comparator[Keyed[ComparatorKeyType]], Generic[ComparatorKeyType]
): ):
def __init__(self, resolver: HashResolver, comparator: Comparator[ComparatorKeyType]): def __init__(self, comparator: Comparator[ComparatorKeyType]):
assert isinstance(resolver, HashResolver)
assert isinstance(comparator, Comparator) assert isinstance(comparator, Comparator)
self.comparator = comparator self.comparator = comparator
super().__init__(resolver) super().__init__(comparator.resolver)
def compare( def compare(
self, self,

View File

@ -10,8 +10,10 @@ class PlainComparator(ProtocolComparator[Plain]):
def compare(self, original: HashPoint[Plain], key: HashPoint[Plain]) -> Comparison: 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 = self.resolver.resolve(original) original_value: Plain = self.resolver.resolve(original)
key_value = self.resolver.resolve(key) assert isinstance(original_value, Plain)
key_value: Plain = self.resolver.resolve(key)
assert isinstance(key, Plain)
if key_value.source < original_value.source: if key_value.source < original_value.source:
return Left() return Left()
elif key_value.source > original_value.source: elif key_value.source > original_value.source:

View File

@ -1,13 +1,17 @@
from typing import TypeVar
from rainbowadn.hashing.rainbow_factory import RainbowFactory from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('HashMentionable',) __all__ = ('HashMentionable',)
HashMentioned = TypeVar('HashMentioned')
class HashMentionable: class HashMentionable:
def __bytes__(self): def __bytes__(self):
raise NotImplementedError raise NotImplementedError
def __factory__(self) -> RainbowFactory['HashMentionable']: def __factory__(self: HashMentioned) -> RainbowFactory[HashMentioned]:
raise NotImplementedError raise NotImplementedError
def __topology_hash__(self) -> bytes: def __topology_hash__(self) -> bytes:

View File

@ -12,6 +12,11 @@ __all__ = ('HashPoint',)
HashMentioned = TypeVar('HashMentioned') HashMentioned = TypeVar('HashMentioned')
def _hash(source: bytes) -> bytes:
assert isinstance(source, bytes)
return hashlib.sha256(source).digest()
class HashPoint(Generic[HashMentioned]): class HashPoint(Generic[HashMentioned]):
def __init__(self, factory: RainbowFactory[HashMentioned], point: bytes, value: Nullable[HashMentioned]): def __init__(self, factory: RainbowFactory[HashMentioned], point: bytes, value: Nullable[HashMentioned]):
assert isinstance(factory, RainbowFactory) assert isinstance(factory, RainbowFactory)
@ -25,13 +30,13 @@ class HashPoint(Generic[HashMentioned]):
def __bytes__(self): def __bytes__(self):
return self.point return self.point
HASH_LENGTH = 32 HASH_LENGTH = len(_hash(b''))
NULL_HASH = b'\0' * HASH_LENGTH NULL_HASH = b'\0' * HASH_LENGTH
@classmethod @classmethod
def hash(cls, source: bytes) -> bytes: def hash(cls, source: bytes) -> bytes:
assert isinstance(source, bytes) assert isinstance(source, bytes)
return hashlib.sha256(source).digest() return _hash(source)
@classmethod @classmethod
def bytes_of_mentioned(cls, mentioned: HashMentionable): def bytes_of_mentioned(cls, mentioned: HashMentionable):

View File

@ -9,16 +9,16 @@ __all__ = ('StaticMentionable', 'StaticFactory',)
StaticMentioned = TypeVar('StaticMentioned') StaticMentioned = TypeVar('StaticMentioned')
class StaticMentionable(HashMentionable, abc.ABC, Generic[StaticMentioned]): class StaticMentionable(HashMentionable, abc.ABC):
@classmethod @classmethod
def from_bytes(cls, source: bytes) -> StaticMentioned: def from_bytes(cls: Type[StaticMentioned], source: bytes) -> StaticMentioned:
raise NotImplementedError raise NotImplementedError
def __factory__(self) -> RainbowFactory[StaticMentioned]: def __factory__(self) -> RainbowFactory[StaticMentioned]:
return self.factory() return self.factory()
@classmethod @classmethod
def factory(cls) -> RainbowFactory[StaticMentioned]: def factory(cls: Type[StaticMentioned]) -> RainbowFactory[StaticMentioned]:
return StaticFactory(cls) return StaticFactory(cls)

View File

@ -3,7 +3,7 @@ from typing import Iterable
from rainbowadn.data.atomic.integer import Integer from rainbowadn.data.atomic.integer import Integer
from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory
from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinaryTree from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinaryTree
from rainbowadn.data.collection.trees.binary.avl import AVLABT from rainbowadn.data.collection.trees.binary.avl import AVLBTBP
from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, BinaryTreeFactory from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, BinaryTreeFactory
from rainbowadn.data.collection.trees.comparison.comparator import Fail from rainbowadn.data.collection.trees.comparison.comparator import Fail
from rainbowadn.data.collection.trees.comparison.hashcomparator import HashComparator from rainbowadn.data.collection.trees.comparison.hashcomparator import HashComparator
@ -24,7 +24,7 @@ from rainbowadn.v13.transaction import Coin, Transaction, TransactionData
__all__ = ('BankState',) __all__ = ('BankState',)
class BankState(RecursiveMentionable, StaticMentionable['BankState']): class BankState(RecursiveMentionable, StaticMentionable):
def __init__( def __init__(
self, self,
minted: NullableReference[BinaryTree[KeyMetadata[Coin, Integer]]], minted: NullableReference[BinaryTree[KeyMetadata[Coin, Integer]]],
@ -107,9 +107,13 @@ class BankState(RecursiveMentionable, StaticMentionable['BankState']):
transaction_data: TransactionData = resolver.resolve(transaction_resolved.data) transaction_data: TransactionData = resolver.resolve(transaction_resolved.data)
assert isinstance(transaction_data, TransactionData) assert isinstance(transaction_data, TransactionData)
minted: ActiveBinaryTree[Coin, Integer] = AVLABT(HashComparator(resolver, Fail()), self.minted) minted: ActiveBinaryTree[Coin, Integer] = ActiveBinaryTree(
AVLBTBP(HashComparator(resolver, Fail())), self.minted
)
assert isinstance(minted, ActiveBinaryTree) assert isinstance(minted, ActiveBinaryTree)
used: ActiveBinaryTree[Coin, Integer] = AVLABT(HashComparator(resolver, Fail()), self.used) used: ActiveBinaryTree[Coin, Integer] = ActiveBinaryTree(
AVLBTBP(HashComparator(resolver, Fail())), self.used
)
assert isinstance(used, ActiveBinaryTree) assert isinstance(used, ActiveBinaryTree)
in_coin: HashPoint[Coin] in_coin: HashPoint[Coin]

View File

@ -13,7 +13,7 @@ class BadSignature(nacl.exceptions.BadSignatureError):
pass pass
class Signature(Atomic['Signature']): 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 len(source) == nacl.bindings.crypto_sign_BYTES

View File

@ -6,7 +6,7 @@ from rainbowadn.data.atomic.atomic import Atomic
__all__ = ('Subject',) __all__ = ('Subject',)
class Subject(Atomic['Subject']): class Subject(Atomic):
def __init__(self, verify_key: VerifyKey): def __init__(self, verify_key: VerifyKey):
assert isinstance(verify_key, VerifyKey) assert isinstance(verify_key, VerifyKey)
self.verify_key: VerifyKey = verify_key self.verify_key: VerifyKey = verify_key

View File

@ -20,7 +20,7 @@ from rainbowadn.v13.subject import Subject
__all__ = ('CoinData', 'Coin', 'TransactionData', 'Transaction',) __all__ = ('CoinData', 'Coin', 'TransactionData', 'Transaction',)
class CoinData(RecursiveMentionable, StaticMentionable['CoinData']): class CoinData(RecursiveMentionable, StaticMentionable):
def __init__( def __init__(
self, self,
owner: HashPoint[Subject], owner: HashPoint[Subject],
@ -56,7 +56,7 @@ class CoinData(RecursiveMentionable, StaticMentionable['CoinData']):
f'{tabulate(tab)}{resolver.resolve(self.value)}' f'{tabulate(tab)}{resolver.resolve(self.value)}'
class Coin(RecursiveMentionable, StaticMentionable['Coin']): class Coin(RecursiveMentionable, StaticMentionable):
def __init__( def __init__(
self, self,
data: HashPoint[CoinData], data: HashPoint[CoinData],
@ -99,7 +99,7 @@ class Coin(RecursiveMentionable, StaticMentionable['Coin']):
f'{tabulate(tab)})' f'{tabulate(tab)})'
class TransactionData(RecursiveMentionable, StaticMentionable['TransactionData']): class TransactionData(RecursiveMentionable, StaticMentionable):
def __init__( def __init__(
self, self,
in_coins: NullableReference[Stack[Coin]], in_coins: NullableReference[Stack[Coin]],
@ -250,7 +250,7 @@ class TransactionData(RecursiveMentionable, StaticMentionable['TransactionData']
f'{tabulate(tab)}{self.out_coins.str(resolver, tab)}' f'{tabulate(tab)}{self.out_coins.str(resolver, tab)}'
class Transaction(RecursiveMentionable, StaticMentionable['Transaction']): class Transaction(RecursiveMentionable, StaticMentionable):
def __init__( def __init__(
self, self,
data: HashPoint[TransactionData], data: HashPoint[TransactionData],

View File

View File

@ -0,0 +1,312 @@
import bisect
from typing import Iterable, Sequence
from rainbowadn.hashing.hash_point_format import hash_point_format, tabulate
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
from rainbowadn.hashing.nullability.notnull import NotNull
from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.nullability.nullable import Nullable
from rainbowadn.hashing.rainbow_factory import RainbowFactory
from rainbowadn.hashing.recursivementionable import RecursiveMentionable
__all__ = ('WeakReferenceIndexSetBTree', 'WrisbtFactory',)
class WeakReferenceIndexSetBTree(RecursiveMentionable):
def __init__(
self,
source: bytes,
height: int,
keymin: int,
root: bool,
cache: tuple[Nullable['WeakReferenceIndexSetBTree'], ...]
):
assert isinstance(source, bytes)
assert isinstance(height, int)
assert isinstance(keymin, int)
assert isinstance(root, bool)
assert isinstance(cache, tuple)
self.length = len(source) // HashPoint.HASH_LENGTH
assert len(source) == self.length * HashPoint.HASH_LENGTH
self.source = source
assert height >= 0
self.height = height
self.leaf = height == 0
self.empty = self.length == 0
if self.empty:
assert self.leaf
if self.leaf:
self.keys = self.length
self.children = 0
else:
self.keys = self.length // 2
self.children = self.keys + 1
assert self.length == self.keys + self.children
assert keymin > 0
self.keymin = keymin
self.root = root
if not root:
assert keymin <= self.keys
assert self.keys <= 2 * keymin + 1
assert len(cache) == self.children
child_index: int
cached: Nullable[WeakReferenceIndexSetBTree]
self.cache = cache
if self.balanced():
self._hash_point = HashPoint.of(self)
def hash_point(self) -> HashPoint['WeakReferenceIndexSetBTree']:
return self._hash_point
def full(self) -> bool:
return self.keys == 2 * self.keymin + 1
def bytes_no(self, index: int) -> bytes:
assert isinstance(index, int)
assert 0 <= index < self.length
return self.source[HashPoint.HASH_LENGTH * index:HashPoint.HASH_LENGTH * (index + 1)]
def key_no(self, index: int) -> bytes:
assert isinstance(index, int)
assert 0 <= index < self.keys
return self.bytes_no(index)
def cached_no(self, index: int) -> Nullable['WeakReferenceIndexSetBTree']:
assert isinstance(index, int)
assert 0 <= index < self.children
assert not self.leaf
cached: Nullable[WeakReferenceIndexSetBTree] = self.cache[index]
assert isinstance(cached, Nullable)
if isinstance(cached, NotNull):
tree: WeakReferenceIndexSetBTree = cached.value
assert self.bytes_no(self.keys + index) == tree.hash_point().point
return cached
def child_no(self, index: int) -> HashPoint['WeakReferenceIndexSetBTree']:
assert isinstance(index, int)
assert 0 <= index < self.children
assert not self.leaf
return HashPoint(
WrisbtFactory(self.height - 1, self.keymin, False),
self.bytes_no(self.keys + index),
self.cached_no(index)
)
def balanced(self) -> bool:
return self.keys <= 2 * self.keymin
def points(self) -> Iterable[HashPoint]:
assert self.balanced()
if self.leaf:
return []
else:
return [self.child_no(child_index) for child_index in range(self.children)]
def __bytes__(self):
assert self.balanced()
return self.source
def __topology_hash__(self) -> bytes:
return HashPoint.hash(self.source[self.keys * HashPoint.HASH_LENGTH:])
def __factory__(self) -> RainbowFactory['WeakReferenceIndexSetBTree']:
assert self.balanced()
return WrisbtFactory(self.height, self.keymin, self.root)
def range(self, left: int, right: int) -> 'WeakReferenceIndexSetBTree':
assert isinstance(left, int)
assert isinstance(right, int)
assert 0 <= left < right <= self.keys
hl: int = HashPoint.HASH_LENGTH
assert isinstance(hl, int)
if self.leaf:
return WeakReferenceIndexSetBTree(
self.source[hl * left:hl * right],
0,
self.keymin,
False,
()
)
else:
keybytes: bytes = self.source[hl * left:hl * right]
assert isinstance(keybytes, bytes)
childbytes: bytes = self.source[hl * (self.keys + left):hl * (self.keys + right + 1)]
assert isinstance(childbytes, bytes)
return WeakReferenceIndexSetBTree(
keybytes + childbytes,
self.height,
self.keymin,
False,
self.cache[left:right + 1],
)
def split(self) -> tuple['WeakReferenceIndexSetBTree', bytes, 'WeakReferenceIndexSetBTree']:
assert self.full()
return (
self.range(0, self.keymin),
self.key_no(self.keymin),
self.range(self.keymin + 1, 2 * self.keymin + 1),
)
def str(self, resolver: HashResolver, tab: int) -> str:
assert isinstance(resolver, HashResolver)
assert isinstance(tab, int)
formatted = f'{self.height}' \
f'{tabulate(tab)}('
for key_index in range(self.keys):
formatted += f'{tabulate(tab + 1)}{self.key_no(key_index).hex()}'
for child_index in range(self.children):
formatted += f'{tabulate(tab + 1)}{hash_point_format(self.child_no(child_index), resolver, tab + 1)}'
return f'{formatted}' \
f'{tabulate(tab)})'
def contains(self, resolver: HashResolver, key: bytes) -> bool:
assert isinstance(resolver, HashResolver)
assert isinstance(key, bytes)
assert len(key) == HashPoint.HASH_LENGTH
hl: int = HashPoint.HASH_LENGTH
assert isinstance(hl, int)
assert self.balanced()
index: int = bisect.bisect_left(KeyView(self), key)
assert isinstance(index, int)
if index < self.keys and self.key_no(index) == key:
return True
if index < self.keys:
assert key < self.key_no(index)
if index > 0:
assert key > self.key_no(index - 1)
if self.leaf:
return False
child: WeakReferenceIndexSetBTree = resolver.resolve(self.child_no(index))
assert isinstance(child, WeakReferenceIndexSetBTree)
return child.contains(resolver, key)
def add(self, resolver: HashResolver, key: bytes) -> 'WeakReferenceIndexSetBTree':
assert isinstance(resolver, HashResolver)
assert isinstance(key, bytes)
assert len(key) == HashPoint.HASH_LENGTH
hl: int = HashPoint.HASH_LENGTH
assert isinstance(hl, int)
assert self.balanced()
index: int = bisect.bisect_left(KeyView(self), key)
assert isinstance(index, int)
if index < self.keys and self.key_no(index) == key:
return self
if index < self.keys:
assert key < self.key_no(index)
if index > 0:
assert key > self.key_no(index - 1)
if self.leaf:
return WeakReferenceIndexSetBTree(
self.source[:hl * index] + key + self.source[hl * index:],
self.height,
self.keymin,
self.root,
()
)
child: WeakReferenceIndexSetBTree = resolver.resolve(self.child_no(index))
assert isinstance(child, WeakReferenceIndexSetBTree)
child: WeakReferenceIndexSetBTree = child.add(resolver, key)
assert isinstance(child, WeakReferenceIndexSetBTree)
if child.full():
left, middle, right = child.split()
assert isinstance(left, WeakReferenceIndexSetBTree)
assert isinstance(middle, bytes)
assert isinstance(right, WeakReferenceIndexSetBTree)
return WeakReferenceIndexSetBTree(
(
self.source[:hl * index]
+
middle
+
self.source[hl * index:hl * (self.keys + index)]
+
bytes(left.hash_point())
+
bytes(right.hash_point())
+
self.source[hl * (self.keys + index + 1):]
),
self.height,
self.keymin,
self.root,
self.cache[:index] + (NotNull(left), NotNull(right)) + self.cache[index + 1:]
)
else:
return WeakReferenceIndexSetBTree(
(
self.source[:hl * (self.keys + index)]
+
bytes(HashPoint.of(child))
+
self.source[hl * (self.keys + index + 1):]
),
self.height,
self.keymin,
self.root,
self.cache[:index] + (NotNull(child),) + self.cache[index + 1:]
)
def iter_keys(self, resolver: HashResolver) -> Iterable[bytes]:
if self.leaf:
for key_index in range(self.keys):
yield self.key_no(key_index)
else:
for index in range(self.length):
real_index, mode = divmod(index, 2)
if mode:
yield self.key_no(real_index)
else:
yield from resolver.resolve(self.child_no(real_index)).iter_keys(resolver)
class KeyView(Sequence[WeakReferenceIndexSetBTree]):
def __init__(self, wrisbt: WeakReferenceIndexSetBTree):
assert isinstance(wrisbt, WeakReferenceIndexSetBTree)
self.wrisbt = wrisbt
def __len__(self):
return self.wrisbt.keys
def __getitem__(self, index: int) -> bytes:
return self.wrisbt.key_no(index)
class WrisbtFactory(RainbowFactory[WeakReferenceIndexSetBTree]):
def __init__(self, height: int, keymin: int, root: bool):
assert isinstance(height, int)
assert isinstance(keymin, int)
assert isinstance(root, bool)
assert height >= 0
self.height = height
assert keymin > 0
self.keymin = keymin
self.root = root
def from_bytes(self, source: bytes) -> WeakReferenceIndexSetBTree:
assert isinstance(source, bytes)
return WeakReferenceIndexSetBTree(
source,
self.height,
self.keymin,
self.root,
(Null(),) * (len(source) // (2 * HashPoint.HASH_LENGTH) + 1) if self.height else ()
)

View File

@ -0,0 +1,45 @@
from typing import Generic, TypeVar
from rainbowadn.chain.blockchainprotocol import BlockChainProtocol
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
from rainbowadn.hashing.rainbow_factory import RainbowFactory
from rainbowadn.wrisbt.wrisbtindex import WrisbtIndex, WrisbtIndexFactory
from rainbowadn.wrisbt.wrisbtprotocol import WrisbtProtocol
from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot, WrisbtRootFactory
__all__ = ('WrisbtChainProtocol',)
TargetType = TypeVar('TargetType')
class WrisbtChainProtocol(
BlockChainProtocol[
TargetType,
WrisbtIndex,
WrisbtRoot
],
Generic[TargetType]
):
def __init__(
self,
resolver: HashResolver,
total_factory: RainbowFactory[TargetType],
keymin: int
):
assert isinstance(total_factory, RainbowFactory)
assert isinstance(keymin, int)
assert keymin >= 2
self.keymin = keymin
super().__init__(
WrisbtProtocol(resolver, keymin),
total_factory,
WrisbtIndexFactory(keymin)
)
self.total_factory = total_factory
def actual_state_factory(self) -> RainbowFactory[WrisbtRoot]:
return WrisbtRootFactory(self.keymin)
def actual_state(self, state: WrisbtIndex) -> HashPoint[WrisbtRoot]:
return state.total

View File

@ -0,0 +1,60 @@
from typing import Iterable
from rainbowadn.hashing.hash_point_format import hash_point_format, tabulate
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.rainbow_factory import RainbowFactory
from rainbowadn.hashing.recursivementionable import RecursiveMentionable
from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot, WrisbtRootFactory
__all__ = ('WrisbtIndex', 'WrisbtIndexFactory',)
class WrisbtIndex(RecursiveMentionable):
def __init__(
self,
total: HashPoint[WrisbtRoot],
delta: HashPoint[WrisbtRoot],
keymin: int
):
assert isinstance(total, HashPoint)
assert isinstance(delta, HashPoint)
assert isinstance(keymin, int)
self.total = total
self.delta = delta
assert keymin >= 2
self.keymin = keymin
def points(self) -> Iterable[HashPoint]:
return [self.total, self.delta]
def __bytes__(self):
return bytes(self.total) + bytes(self.delta)
def __factory__(self) -> RainbowFactory['WrisbtIndex']:
return WrisbtIndexFactory(self.keymin)
def str(self, resolver: HashResolver, tab: int) -> str:
assert isinstance(resolver, HashResolver)
assert isinstance(tab, int)
return f'(index)' \
f'{tabulate(tab)}{hash_point_format(self.total, resolver, tab)}' \
f'{tabulate(tab)}{hash_point_format(self.delta, resolver, tab)}'
class WrisbtIndexFactory(RainbowFactory[WrisbtIndex]):
def __init__(self, keymin: int):
assert isinstance(keymin, int)
assert keymin >= 2
self.keymin = keymin
self.root_factory: RainbowFactory[WrisbtRoot] = WrisbtRootFactory(keymin)
assert isinstance(self.root_factory, RainbowFactory)
def from_bytes(self, source: bytes) -> WrisbtIndex:
assert isinstance(source, bytes)
return WrisbtIndex(
HashPoint(self.root_factory, source[:HashPoint.HASH_LENGTH], Null()),
HashPoint(self.root_factory, source[HashPoint.HASH_LENGTH:], Null()),
self.keymin
)

View File

@ -0,0 +1,52 @@
from typing import TypeVar
from rainbowadn.chain.states.activestateprotocol import ActiveStateProtocol
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
from rainbowadn.wrisbt.wrisbtindex import WrisbtIndex
from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot
__all__ = ('WrisbtProtocol',)
TargetType = TypeVar('TargetType')
class WrisbtProtocol(ActiveStateProtocol[TargetType, WrisbtIndex]):
def __init__(self, resolver: HashResolver, keymin: int):
assert isinstance(resolver, HashResolver)
assert isinstance(keymin, int)
super().__init__(resolver)
assert keymin >= 2
self.keymin = keymin
def _initial_state(self) -> HashPoint[WrisbtIndex]:
return HashPoint.of(
WrisbtIndex(
HashPoint.of(WrisbtRoot.empty(self.keymin)),
HashPoint.of(WrisbtRoot.empty(self.keymin)),
self.keymin
)
)
def _derive(
self,
previous: HashPoint[WrisbtIndex],
header: HashPoint[TargetType]
) -> HashPoint[WrisbtIndex]:
assert isinstance(previous, HashPoint)
assert isinstance(header, HashPoint)
index = self.resolver.resolve(previous)
assert isinstance(index, WrisbtIndex)
empty: WrisbtRoot = WrisbtRoot.empty(self.keymin)
assert isinstance(empty, WrisbtRoot)
total: WrisbtRoot = self.resolver.resolve(index.total)
assert isinstance(total, WrisbtRoot)
return HashPoint.of(
WrisbtIndex(
HashPoint.of(total.index(self.resolver, header, empty)),
HashPoint.of(empty.index(self.resolver, header, total)),
index.keymin
)
)

View File

@ -0,0 +1,123 @@
from typing import Iterable, Optional
from rainbowadn.data.atomic.integer import Integer
from rainbowadn.wrisbt.weakreferenceindexsetbtree import WeakReferenceIndexSetBTree, WrisbtFactory
from rainbowadn.hashing.hash_point_format import hash_point_format, tabulate
from rainbowadn.hashing.hashmentionable import HashMentionable
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
from rainbowadn.hashing.nullability.notnull import NotNull
from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.rainbow_factory import RainbowFactory
from rainbowadn.hashing.recursivementionable import RecursiveMentionable
__all__ = ('WrisbtRoot','WrisbtRootFactory',)
class WrisbtRoot(RecursiveMentionable):
def __init__(self, root: HashPoint[WeakReferenceIndexSetBTree], height: int, keymin: int):
assert isinstance(root, HashPoint)
assert isinstance(height, int)
assert isinstance(keymin, int)
self.root = root
self.height = height
self.keymin = keymin
def points(self) -> Iterable[HashPoint]:
return [self.root]
def __bytes__(self):
return bytes(self.root) + bytes(Integer(self.height))
def __factory__(self) -> RainbowFactory['WrisbtRoot']:
return WrisbtRootFactory(self.keymin)
@classmethod
def empty(cls, keymin: int) -> 'WrisbtRoot':
assert isinstance(keymin, int)
return WrisbtRoot(HashPoint.of(WeakReferenceIndexSetBTree(b'', 0, keymin, True, ())), 0, keymin)
def str(self, resolver: HashResolver, tab: int) -> str:
assert isinstance(resolver, HashResolver)
assert isinstance(tab, int)
return f'(root)' \
f'{tabulate(tab)}{self.height}' \
f'{tabulate(tab)}{hash_point_format(self.root, resolver, tab)}'
def contains(self, resolver: HashResolver, key: bytes) -> bool:
assert isinstance(resolver, HashResolver)
assert isinstance(key, bytes)
assert len(key) == HashPoint.HASH_LENGTH
root: WeakReferenceIndexSetBTree = resolver.resolve(self.root)
assert isinstance(root, WeakReferenceIndexSetBTree)
return root.contains(resolver, key)
def add(self, resolver: HashResolver, key: bytes) -> 'WrisbtRoot':
assert isinstance(resolver, HashResolver)
assert isinstance(key, bytes)
assert len(key) == HashPoint.HASH_LENGTH
root: WeakReferenceIndexSetBTree = resolver.resolve(self.root).add(resolver, key)
assert isinstance(root, WeakReferenceIndexSetBTree)
if root.full():
left, middle, right = root.split()
assert isinstance(left, WeakReferenceIndexSetBTree)
assert isinstance(middle, bytes)
assert isinstance(right, WeakReferenceIndexSetBTree)
root = WeakReferenceIndexSetBTree(
middle + bytes(HashPoint.of(left)) + bytes(HashPoint.of(right)),
root.height + 1,
root.keymin,
True,
(NotNull(left), NotNull(right))
)
assert isinstance(root, WeakReferenceIndexSetBTree)
return self.of(root)
@classmethod
def of(cls, root: WeakReferenceIndexSetBTree) -> 'WrisbtRoot':
assert isinstance(root, WeakReferenceIndexSetBTree)
return cls(HashPoint.of(root), root.height, root.keymin)
def keys(self, resolver: HashResolver) -> list[bytes]:
return list(resolver.resolve(self.root).iter_keys(resolver))
def index(
self, resolver: HashResolver, target: HashPoint, exclude: Optional['WrisbtRoot']
) -> 'WrisbtRoot':
assert isinstance(resolver, HashResolver)
assert isinstance(target, HashPoint)
if exclude is None:
exclude = self.empty(self.keymin)
assert isinstance(exclude, WrisbtRoot)
key: bytes = target.point
assert isinstance(key, bytes)
if exclude.contains(resolver, key) or self.contains(resolver, key):
return self
tree = self
value: HashMentionable = resolver.resolve(target)
assert isinstance(value, HashMentionable)
if isinstance(value, RecursiveMentionable):
for hash_point in value.points():
tree = tree.index(resolver, hash_point, exclude)
tree = tree.add(resolver, key)
return tree
class WrisbtRootFactory(RainbowFactory[WrisbtRoot]):
def __init__(self, keymin: int):
assert isinstance(keymin, int)
self.keymin = keymin
def from_bytes(self, source: bytes) -> WrisbtRoot:
assert isinstance(source, bytes)
height: int = Integer.from_bytes(source[HashPoint.HASH_LENGTH:]).integer
assert isinstance(height, int)
return WrisbtRoot(
HashPoint(WrisbtFactory(height, self.keymin, True), source[:HashPoint.HASH_LENGTH], Null()),
height,
self.keymin
)