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 typing import MutableMapping
from typing import Any, MutableMapping
import nacl.signing
from rainbowadn.chain.blockchain import BlockChainFactory
from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface
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.hashpoint import HashPoint
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.subject import Subject
from rainbowadn.v13.transaction import CoinData, Transaction
from rainbowadn.wrisbt.wrisbtchainprotocol import WrisbtChainProtocol
from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot
class DumbResolver(HashResolver):
@ -37,7 +50,7 @@ class DumbResolver(HashResolver):
raise TypeError
def main():
def main0():
dr = DumbResolver()
bank = BankChain.empty(ReductionChainMetaFactory(), dr)
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)
print(bank)
print(bank.verify())
for key, value in dr.table.items():
print(key.hex(), value.hex())
# for key, value in dr.table.items():
# 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__':

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:
raise TypeError
def _base_state_factory(self) -> RainbowFactory[ActualStateType]:
def _actual_state_factory(self) -> RainbowFactory[ActualStateType]:
raise NotImplementedError
def _base_state(self, block: BlockType) -> HashPoint[ActualStateType]:
def _actual_state(self, block: BlockType) -> HashPoint[ActualStateType]:
raise NotImplementedError
def base_state(self) -> NullableReference[ActualStateType]:
def actual_state(self) -> NullableReference[ActualStateType]:
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):
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:
raise TypeError

View File

@ -19,3 +19,6 @@ class ChainCollectionFactory(Generic[BlockType, HeaderType, ActualStateType]):
reference: NullableReference[BlockType]
) -> ChainCollectionInterface[BlockType, HeaderType, ActualStateType]:
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.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.reductionchainfactory import ReductionChainFactory
from rainbowadn.chain.reduction.reductionchainprotocol import ReductionChainProtocol
from rainbowadn.chain.reduction.reductionprotocol import ReductionProtocol
from rainbowadn.chain.stages.stage import StateStage
from rainbowadn.hashing.rainbow_factory import RainbowFactory
@ -34,9 +36,25 @@ class ReductionChainMetaFactory(
reductor_factory: RainbowFactory[ReductorType],
accumulator_factory: RainbowFactory[AccumulatorType],
protocol: ReductionProtocol[ReductorType, AccumulatorType],
):
return ReductionChainFactory(
) -> ChainCollectionFactory[
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,
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(
self,
stage: StageStage[HeaderType, BaseStateType, StageType],
stage_factory: RainbowFactory[StageType]
) -> HashPoint[StateStage[HeaderType, BaseStateType, StageType]]:
assert isinstance(stage, StageStage)
assert isinstance(stage_factory, RainbowFactory)
while True:
derived = self.derive_stage_or_state(stage.stage)
assert isinstance(derived, Derived)
@ -65,7 +67,7 @@ class ActiveStageProtocol(
stage = StageStage(self, NullableReference.off(stage), derived.stage)
assert isinstance(stage, StageStage)
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:
raise TypeError
@ -109,7 +111,8 @@ class ActiveStageProtocol(
),
header,
stage_factory
)
),
stage_factory
)
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,
protocol: StageProtocol[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(previous, HashPoint)
assert isinstance(state, HashPoint)
assert isinstance(stage_factory, RainbowFactory)
super().__init__(protocol)
self.previous = previous
self.state = state
self.stage_factory = stage_factory
def verify(
self,
@ -181,7 +184,7 @@ class StateStage(
def __factory__(self) -> RainbowFactory['StateStage[HeaderType, BaseStateType, StageType]']:
return StateStageFactory(
self.protocol,
self.previous.factory,
self.stage_factory,
self.state.factory
)
@ -196,20 +199,27 @@ class StateStageFactory(RainbowFactory[StateStage[HeaderType, BaseStateType, Sta
def __init__(
self,
protocol: StageProtocol[HeaderType, BaseStateType, StageType],
stage_stage_factory: RainbowFactory[StageStage[HeaderType, BaseStateType, StageType]],
stage_factory: RainbowFactory[StageType],
state_factory: RainbowFactory[BaseStateType]
):
assert isinstance(protocol, StageProtocol)
assert isinstance(stage_stage_factory, RainbowFactory)
assert isinstance(stage_factory, RainbowFactory)
assert isinstance(state_factory, RainbowFactory)
self.protocol = protocol
self.stage_stage_factory = stage_stage_factory
self.stage_factory = stage_factory
self.state_factory = state_factory
def from_bytes(self, source: bytes) -> StateStage[HeaderType, BaseStateType, StageType]:
assert isinstance(source, bytes)
return StateStage(
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()),
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,
previous: NullableReference[StateType],
header: HashPoint[HeaderType],
state: NullableReference[StateType]
state: HashPoint[StateType]
) -> bool:
raise NotImplementedError

View File

@ -1,5 +1,5 @@
import abc
from typing import Generic, TypeVar
from typing import TypeVar
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.static import StaticMentionable
@ -9,6 +9,6 @@ __all__ = ('Atomic',)
AtomicMentioned = TypeVar('AtomicMentioned')
class Atomic(StaticMentionable[AtomicMentioned], abc.ABC, Generic[AtomicMentioned]):
class Atomic(StaticMentionable, abc.ABC):
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',)
class Integer(Atomic['Integer']):
class Integer(Atomic):
def __init__(self, integer: int):
assert isinstance(integer, int)
assert integer >= 0

View File

@ -3,7 +3,7 @@ from rainbowadn.data.atomic.atomic import Atomic
__all__ = ('Plain',)
class Plain(Atomic['Plain']):
class Plain(Atomic):
def __init__(self, source: bytes):
assert isinstance(source, bytes)
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)
reference: NullableReference[Stack[ElementType]] = NullableReference(Null(), cls.factory(factory))
assert isinstance(reference, NullableReference)
for element in elements:
assert isinstance(element, HashPoint)
reference = NullableReference.off(cls(reference, element))
assert isinstance(reference, NullableReference)
return reference
@classmethod
@ -63,6 +65,7 @@ class Stack(RecursiveMentionable, Generic[ElementType]):
) -> NullableReference[
'Stack[ElementType]'
]:
assert isinstance(factory, RainbowFactory)
return cls.of(factory, map(HashPoint.of, elements))

View File

@ -1,19 +1,22 @@
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.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.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.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.nullability.nullablereference import NullableReference
from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('ActiveBinaryTree',)
@ -27,40 +30,34 @@ class ActiveBinaryTree(
):
def __init__(
self,
comparator: Comparator[ActiveKeyType],
protocol: BinaryTreeBalancingProtocol[ActiveKeyType, MetaDataType, 'ActiveBinaryTree'],
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
):
assert isinstance(comparator, Comparator)
assert isinstance(protocol, BinaryTreeBalancingProtocol)
assert isinstance(reference, NullableReference)
super().__init__(reference)
self.comparator = comparator
self.resolver = comparator.resolver
self.protocol = protocol
self.comparator = protocol.comparator
assert isinstance(self.comparator, Comparator)
self.resolver = protocol.resolver
assert isinstance(self.resolver, HashResolver)
self.creation = ActiveCreationProtocol(protocol)
assert isinstance(self.creation, BinaryTreeCreationProtocol)
def empty_metadata(self) -> HashPoint[MetaDataType]:
raise NotImplementedError
def metadata(
self,
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
key: HashPoint[ActiveKeyType]
) -> HashPoint[MetaDataType]:
raise NotImplementedError
def _binary_tree(
self,
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)))
@classmethod
def empty(
cls,
protocol: BinaryTreeBalancingProtocol[ActiveKeyType, MetaDataType, 'ActiveBinaryTree'],
factory: RainbowFactory[ActiveKeyType]
):
assert isinstance(protocol, BinaryTreeBalancingProtocol)
assert isinstance(factory, RainbowFactory)
return cls(
protocol,
NullableReference(
Null(),
BinaryTreeFactory(KeyMetadataFactory(factory, protocol.empty_metadata().factory))
)
)
def create(
@ -68,81 +65,82 @@ class ActiveBinaryTree(
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
assert isinstance(reference, NullableReference)
return type(self)(
self.comparator,
return ActiveBinaryTree(
self.protocol,
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]':
assert isinstance(key, HashPoint)
reference: Nullable[
HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
] = self.reference.reference
assert isinstance(reference, Nullable)
if isinstance(reference, Null):
return self.active_tree(self.reference, self.reference, key)
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
if self.creation.splittable(self):
treel: ActiveBinaryTree[ActiveKeyType, MetaDataType]
original: HashPoint[ActiveKeyType]
treer: ActiveBinaryTree[ActiveKeyType, MetaDataType]
treel, original, _, treer = self.creation.split(self)
assert isinstance(treel, ActiveBinaryTree)
assert isinstance(original, HashPoint)
assert isinstance(treer, ActiveBinaryTree)
comparison: Comparison = self.comparator.compare(original, key)
assert isinstance(comparison, Comparison)
if isinstance(comparison, Replace):
return self.active_tree(tree.treel, tree.treer, key)
return self.creation.tree(treel, treer, key)
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):
return self.active_tree(tree.treel, self.create(tree.treer).add(key).reference, original)
return self.creation.tree(treel, treer.add(key), original)
else:
raise TypeError
else:
raise TypeError
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
return self.creation.tree(self, self, key)
def query_tree(self) -> QueryCollectionInterface[ActiveKeyType]:
return KeyMetadataQueryCollection(
self.empty_metadata(),
QueryBinaryTree(KeyedComparator(self.resolver, self.comparator), self.reference),
self.protocol.empty_metadata(),
QueryBinaryTree(KeyedComparator(self.comparator), self.reference),
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.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.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.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')
TreeType = TypeVar('TreeType')
class AVLABT(ActiveBinaryTree[ActiveKeyType, Integer], Generic[ActiveKeyType]):
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()))
)
)
class AVLBTBP(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]):
def empty_metadata(self) -> HashPoint[Integer]:
return HashPoint.of(Integer(0))
def metadata(
self,
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]],
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]],
key: HashPoint[ActiveKeyType]
treel: TreeType,
treer: TreeType,
key: HashPoint[ActiveKeyType],
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
) -> HashPoint[Integer]:
assert isinstance(treel, NullableReference)
assert isinstance(treer, NullableReference)
assert isinstance(key, HashPoint)
return HashPoint.of(Integer(1 + max(self.create(treel).height(), self.create(treer).height())))
return HashPoint.of(
Integer(1 + max(self.height(treel, protocol), self.height(treer, protocol)))
)
def balance(self) -> ActiveBinaryTree[ActiveKeyType, Integer]:
reference: Nullable[
HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]]
] = self.reference.reference
assert isinstance(reference, Nullable)
if isinstance(reference, Null):
return self
elif isinstance(reference, NotNull):
tree: BinaryTree[KeyMetadata[ActiveKeyType, Integer]] = self.resolver.resolve(reference.value)
assert isinstance(tree, BinaryTree)
atl = self.create(tree.treel)
assert isinstance(atl, ActiveBinaryTree)
atr = self.create(tree.treer)
assert isinstance(atr, ActiveBinaryTree)
delta = atl.height() - atr.height()
def height(
self,
tree: TreeType,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
) -> int:
if protocol.splittable(tree):
_, _, metadata, _ = protocol.split(tree)
return self.resolver.resolve(metadata).integer
else:
return 0
def balance(
self,
tree: TreeType,
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)
if delta < -1:
assert isinstance(atr.reference.reference, NotNull)
treer: BinaryTree[
KeyMetadata[ActiveKeyType, Integer]
] = self.resolver.resolve(atr.reference.reference.value)
assert isinstance(treer, BinaryTree)
atrl = self.create(treer.treel)
assert isinstance(atrl, ActiveBinaryTree)
atrr = self.create(treer.treer)
assert isinstance(atrr, ActiveBinaryTree)
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
assert protocol.splittable(treer)
treerl, keyr, _, treerr = protocol.split(treer)
if self.height(treerl, protocol) > self.height(treerr, protocol):
assert protocol.splittable(treerl)
treerll, keyrl, _, treerlr = protocol.split(treerl)
return protocol.tree(
protocol.tree(treel, treerll, key),
protocol.tree(treerlr, treerr, keyr),
keyrl
)
else:
return self.active_tree(
self.active_tree(
atl.reference,
atrl.reference,
self.resolver.resolve(tree.key).key
).reference,
atrr.reference,
self.resolver.resolve(treer.key).key
return protocol.tree(
protocol.tree(treel, treerl, key),
treerr,
keyr
)
elif delta > 1:
assert isinstance(atl.reference.reference, NotNull)
treel: BinaryTree[
KeyMetadata[ActiveKeyType, Integer]
] = self.resolver.resolve(atl.reference.reference.value)
assert isinstance(treel, BinaryTree)
atlr = self.create(treel.treer)
assert isinstance(atlr, ActiveBinaryTree)
atll = self.create(treel.treel)
assert isinstance(atll, ActiveBinaryTree)
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
assert protocol.splittable(treel)
treell, keyl, _, treelr = protocol.split(treel)
if self.height(treelr, protocol) > self.height(treell, protocol):
assert protocol.splittable(treelr)
treelrl, keylr, _, treelrr = protocol.split(treelr)
return protocol.tree(
protocol.tree(treell, treelrl, keyl),
protocol.tree(treelrr, treer, key),
keylr
)
else:
return self.active_tree(
atll.reference,
self.active_tree(
atlr.reference,
atr.reference,
self.resolver.resolve(tree.key).key
).reference,
self.resolver.resolve(treel.key).key
return protocol.tree(
treell,
protocol.tree(treelr, treer, key),
keyl
)
else:
return self
return tree
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 rainbowadn.data.collection.trees.comparison.comparator import Comparator, Comparison
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.hashresolver import HashResolver
__all__ = ('KeyedComparator',)
@ -13,11 +12,10 @@ ComparatorKeyType = TypeVar('ComparatorKeyType')
class KeyedComparator(
Comparator[Keyed[ComparatorKeyType]], Generic[ComparatorKeyType]
):
def __init__(self, resolver: HashResolver, comparator: Comparator[ComparatorKeyType]):
assert isinstance(resolver, HashResolver)
def __init__(self, comparator: Comparator[ComparatorKeyType]):
assert isinstance(comparator, Comparator)
self.comparator = comparator
super().__init__(resolver)
super().__init__(comparator.resolver)
def compare(
self,

View File

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

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@ from typing import Iterable
from rainbowadn.data.atomic.integer import Integer
from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory
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.comparison.comparator import Fail
from rainbowadn.data.collection.trees.comparison.hashcomparator import HashComparator
@ -24,7 +24,7 @@ from rainbowadn.v13.transaction import Coin, Transaction, TransactionData
__all__ = ('BankState',)
class BankState(RecursiveMentionable, StaticMentionable['BankState']):
class BankState(RecursiveMentionable, StaticMentionable):
def __init__(
self,
minted: NullableReference[BinaryTree[KeyMetadata[Coin, Integer]]],
@ -107,9 +107,13 @@ class BankState(RecursiveMentionable, StaticMentionable['BankState']):
transaction_data: TransactionData = resolver.resolve(transaction_resolved.data)
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)
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)
in_coin: HashPoint[Coin]

View File

@ -13,7 +13,7 @@ class BadSignature(nacl.exceptions.BadSignatureError):
pass
class Signature(Atomic['Signature']):
class Signature(Atomic):
def __init__(self, source: bytes):
assert isinstance(source, bytes)
assert len(source) == nacl.bindings.crypto_sign_BYTES

View File

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

View File

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