wrisbt + better bst + better blockchain
This commit is contained in:
parent
244997690d
commit
c743da7bb6
71
main.py
71
main.py
@ -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__':
|
||||
|
232
rainbowadn/chain/blockchain.py
Normal file
232
rainbowadn/chain/blockchain.py
Normal 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
|
||||
)
|
43
rainbowadn/chain/blockchainprotocol.py
Normal file
43
rainbowadn/chain/blockchainprotocol.py
Normal 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
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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,
|
||||
)
|
@ -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,
|
||||
)
|
||||
)
|
||||
|
82
rainbowadn/chain/reduction/reductionchainprotocol.py
Normal file
82
rainbowadn/chain/reduction/reductionchainprotocol.py
Normal 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
|
@ -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(
|
||||
|
@ -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
|
||||
)
|
@ -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
|
||||
)
|
||||
|
52
rainbowadn/chain/states/activestateprotocol.py
Normal file
52
rainbowadn/chain/states/activestateprotocol.py
Normal 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)
|
@ -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
|
||||
|
@ -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'')
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
0
rainbowadn/data/collection/array/__init__.py
Normal file
0
rainbowadn/data/collection/array/__init__.py
Normal file
64
rainbowadn/data/collection/array/array.py
Normal file
64
rainbowadn/data/collection/array/array.py
Normal 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)
|
||||
)
|
||||
)
|
@ -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
|
@ -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))
|
||||
|
||||
|
||||
|
0
rainbowadn/data/collection/trees/b/__init__.py
Normal file
0
rainbowadn/data/collection/trees/b/__init__.py
Normal 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)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
)
|
@ -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
|
@ -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
|
@ -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
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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],
|
||||
|
0
rainbowadn/wrisbt/__init__.py
Normal file
0
rainbowadn/wrisbt/__init__.py
Normal file
312
rainbowadn/wrisbt/weakreferenceindexsetbtree.py
Normal file
312
rainbowadn/wrisbt/weakreferenceindexsetbtree.py
Normal 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 ()
|
||||
)
|
45
rainbowadn/wrisbt/wrisbtchainprotocol.py
Normal file
45
rainbowadn/wrisbt/wrisbtchainprotocol.py
Normal 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
|
60
rainbowadn/wrisbt/wrisbtindex.py
Normal file
60
rainbowadn/wrisbt/wrisbtindex.py
Normal 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
|
||||
)
|
52
rainbowadn/wrisbt/wrisbtprotocol.py
Normal file
52
rainbowadn/wrisbt/wrisbtprotocol.py
Normal 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
|
||||
)
|
||||
)
|
123
rainbowadn/wrisbt/wrisbtroot.py
Normal file
123
rainbowadn/wrisbt/wrisbtroot.py
Normal 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
|
||||
)
|
Loading…
Reference in New Issue
Block a user