key-value inlining and correct verification
This commit is contained in:
parent
19ccb3a5a0
commit
87c3292d62
@ -1,59 +1,41 @@
|
|||||||
from typing import Generic, Iterable, TypeVar
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
from rainbowadn.core import *
|
from rainbowadn.core import *
|
||||||
|
from rainbowadn.inlining import *
|
||||||
from .keyed import *
|
from .keyed import *
|
||||||
|
|
||||||
__all__ = ('KeyValue', 'KeyValueFactory',)
|
__all__ = ('KeyValue',)
|
||||||
|
|
||||||
KVKeyType = TypeVar('KVKeyType')
|
KVKeyType = TypeVar('KVKeyType')
|
||||||
KVValueType = TypeVar('KVValueType')
|
KVValueType = TypeVar('KVValueType')
|
||||||
|
|
||||||
|
|
||||||
class KeyValue(Keyed[KVKeyType], Generic[KVKeyType, KVValueType]):
|
class KeyValue(Keyed[KVKeyType], IAuto, Generic[KVKeyType, KVValueType]):
|
||||||
def __init__(self, key: HashPoint[KVKeyType], value: HashPoint[KVValueType]):
|
value: HashPoint[KVValueType]
|
||||||
|
|
||||||
|
def __init__(self, *args):
|
||||||
|
IAuto.__init__(self, *args)
|
||||||
|
key, self.value = self.hashpoints()
|
||||||
|
Keyed.__init__(self, key)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def off(
|
||||||
|
cls, key: HashPoint[KVKeyType], value: HashPoint[KVValueType]
|
||||||
|
) -> 'KeyValue[KVKeyType, KVValueType]':
|
||||||
assert isinstance(key, HashPoint)
|
assert isinstance(key, HashPoint)
|
||||||
assert isinstance(value, HashPoint)
|
assert isinstance(value, HashPoint)
|
||||||
super().__init__(key)
|
return await cls.from_hashpoints(key, value)
|
||||||
self.value = value
|
|
||||||
|
|
||||||
def points(self) -> Iterable[HashPoint]:
|
@classmethod
|
||||||
return [self.key, self.value]
|
def of(cls, vk: KVKeyType, vv: KVValueType) -> 'KeyValue[KVKeyType, KVValueType]':
|
||||||
|
assert isinstance(vk, Mentionable)
|
||||||
|
assert isinstance(vv, Mentionable)
|
||||||
|
return cls.from_values(vk, vv)
|
||||||
|
|
||||||
def __bytes__(self):
|
@classmethod
|
||||||
return bytes(self.key) + bytes(self.value)
|
def f(
|
||||||
|
cls, f0: RainbowFactory[KVKeyType], f1: RainbowFactory[KVValueType]
|
||||||
def __factory__(self) -> RainbowFactory['KeyValue[KVKeyType, KVValueType]']:
|
) -> RainbowFactory['KeyValue[KVKeyType, KVValueType]']:
|
||||||
return KeyValueFactory(self.key.factory, self.value.factory)
|
assert isinstance(f0, RainbowFactory)
|
||||||
|
assert isinstance(f1, RainbowFactory)
|
||||||
async def str(self, tab: int) -> str:
|
return cls.factory(f0, f1)
|
||||||
assert isinstance(tab, int)
|
|
||||||
key_str, value_str = await gather(
|
|
||||||
hash_point_format(self.key, tab),
|
|
||||||
hash_point_format(self.value, tab)
|
|
||||||
)
|
|
||||||
assert isinstance(key_str, str)
|
|
||||||
assert isinstance(value_str, str)
|
|
||||||
return f'{key_str}' \
|
|
||||||
f'{tabulate(tab)}{value_str}'
|
|
||||||
|
|
||||||
|
|
||||||
class KeyValueFactory(
|
|
||||||
RainbowFactory[KeyValue[KVKeyType, KVValueType]],
|
|
||||||
Generic[KVKeyType, KVValueType]
|
|
||||||
):
|
|
||||||
def __init__(self, key_factory: RainbowFactory[KVKeyType], value_factory: RainbowFactory[KVValueType]):
|
|
||||||
assert isinstance(key_factory, RainbowFactory)
|
|
||||||
assert isinstance(value_factory, RainbowFactory)
|
|
||||||
self.key_factory = key_factory
|
|
||||||
self.value_factory = value_factory
|
|
||||||
|
|
||||||
def from_bytes(self, source: bytes, resolver: HashResolver) -> KeyValue[KVKeyType, KVValueType]:
|
|
||||||
assert isinstance(source, bytes)
|
|
||||||
assert isinstance(resolver, HashResolver)
|
|
||||||
return KeyValue(
|
|
||||||
ResolverOrigin(self.key_factory, source[:HashPoint.HASH_LENGTH], resolver).hash_point(),
|
|
||||||
ResolverOrigin(self.value_factory, source[HashPoint.HASH_LENGTH:], resolver).hash_point(),
|
|
||||||
)
|
|
||||||
|
|
||||||
def loose(self) -> RainbowFactory[KeyValue[KVKeyType, KVValueType]]:
|
|
||||||
return self
|
|
||||||
|
@ -42,6 +42,9 @@ class HashPoint(Generic[Mentioned]):
|
|||||||
assert isinstance(source, bytes)
|
assert isinstance(source, bytes)
|
||||||
return _hash(source)
|
return _hash(source)
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self.point)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def bytes_of_mentioned(cls, mentioned: Mentionable) -> bytes:
|
def bytes_of_mentioned(cls, mentioned: Mentionable) -> bytes:
|
||||||
assert isinstance(mentioned, Mentionable)
|
assert isinstance(mentioned, Mentionable)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
|
from rainbowadn.collection.comparison import *
|
||||||
from rainbowadn.core import *
|
from rainbowadn.core import *
|
||||||
from ._flowstandard import *
|
from ._flowstandard import *
|
||||||
from ._flowtransaction import *
|
from ._flowtransaction import *
|
||||||
@ -11,10 +12,10 @@ class FlowBank(StaticMentionable, RecursiveMentionable):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_bytes(cls, source: bytes, resolver: HashResolver) -> 'FlowBank':
|
def from_bytes(cls, source: bytes, resolver: HashResolver) -> 'FlowBank':
|
||||||
return FlowBank(
|
return FlowBank(
|
||||||
FlowStandardFactory.of(FlowCoin.factory()).from_bytes(
|
FlowStandardFactory.of(FlowCoin.factory(), HashComparator(Fail())).from_bytes(
|
||||||
source[:HashPoint.HASH_LENGTH], resolver
|
source[:HashPoint.HASH_LENGTH], resolver
|
||||||
),
|
),
|
||||||
FlowStandardFactory.of(FlowCoin.factory()).from_bytes(
|
FlowStandardFactory.of(FlowCoin.factory(), HashComparator(Fail())).from_bytes(
|
||||||
source[HashPoint.HASH_LENGTH:], resolver
|
source[HashPoint.HASH_LENGTH:], resolver
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -38,8 +39,8 @@ class FlowBank(StaticMentionable, RecursiveMentionable):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def empty(cls) -> 'FlowBank':
|
def empty(cls) -> 'FlowBank':
|
||||||
return FlowBank(
|
return FlowBank(
|
||||||
FlowStandardFactory.empty(FlowCoin.factory()),
|
FlowStandardFactory.empty(FlowCoin.factory(), HashComparator(Fail())),
|
||||||
FlowStandardFactory.empty(FlowCoin.factory()),
|
FlowStandardFactory.empty(FlowCoin.factory(), HashComparator(Fail())),
|
||||||
)
|
)
|
||||||
|
|
||||||
async def str(self, tab: int) -> str:
|
async def str(self, tab: int) -> str:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from typing import Generic, Iterable, TypeAlias, TypeVar
|
from typing import Generic, Iterable, TypeAlias, TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.collection.comparison import *
|
||||||
from rainbowadn.core import *
|
from rainbowadn.core import *
|
||||||
from rainbowadn.flow.verification.core import *
|
from rainbowadn.flow.verification.core import *
|
||||||
from rainbowadn.nullability import *
|
from rainbowadn.nullability import *
|
||||||
@ -51,7 +52,7 @@ class FlowBlock(Generic[LinkT], RecursiveMentionable):
|
|||||||
@classmethod
|
@classmethod
|
||||||
async def outer_of(cls, factory: RainbowFactory[LinkT], reference: NullableReference[FBL]) -> Index:
|
async def outer_of(cls, factory: RainbowFactory[LinkT], reference: NullableReference[FBL]) -> Index:
|
||||||
if reference.null():
|
if reference.null():
|
||||||
return FlowStandardFactory.empty(FlowBlockFactory(factory))
|
return FlowStandardFactory.empty(FlowBlockFactory(factory), HashComparator(Fail()))
|
||||||
else:
|
else:
|
||||||
return await (await reference.resolve()).outer()
|
return await (await reference.resolve()).outer()
|
||||||
|
|
||||||
@ -102,7 +103,9 @@ class FlowBlockFactory(RainbowFactory[FBL], Generic[LinkT]):
|
|||||||
assert isinstance(resolver, HashResolver)
|
assert isinstance(resolver, HashResolver)
|
||||||
return FlowBlock(
|
return FlowBlock(
|
||||||
NullableReferenceFactory(self).from_bytes(source[:HashPoint.HASH_LENGTH], resolver),
|
NullableReferenceFactory(self).from_bytes(source[:HashPoint.HASH_LENGTH], resolver),
|
||||||
FlowStandardFactory.of(self).from_bytes(source[HashPoint.HASH_LENGTH:2 * HashPoint.HASH_LENGTH], resolver),
|
FlowStandardFactory.of(self, HashComparator(Fail())).from_bytes(
|
||||||
|
source[HashPoint.HASH_LENGTH:2 * HashPoint.HASH_LENGTH], resolver
|
||||||
|
),
|
||||||
ResolverOrigin(self.factory, source[2 * HashPoint.HASH_LENGTH:], resolver).hash_point(),
|
ResolverOrigin(self.factory, source[2 * HashPoint.HASH_LENGTH:], resolver).hash_point(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import itertools
|
import itertools
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
|
from rainbowadn.collection.comparison import *
|
||||||
from rainbowadn.collection.keyvalue import *
|
from rainbowadn.collection.keyvalue import *
|
||||||
from rainbowadn.core import *
|
from rainbowadn.core import *
|
||||||
from rainbowadn.flow.core import *
|
from rainbowadn.flow.core import *
|
||||||
@ -29,16 +30,19 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_bytes(cls, source: bytes, resolver: HashResolver) -> 'FlowCheque':
|
def from_bytes(cls, source: bytes, resolver: HashResolver) -> 'FlowCheque':
|
||||||
return FlowCheque(
|
return FlowCheque(
|
||||||
FlowStandardFactory.of(FlowTransaction.factory()).from_bytes(
|
FlowStandardFactory.of(FlowTransaction.factory(), HashComparator(Fail())).from_bytes(
|
||||||
source[:HashPoint.HASH_LENGTH], resolver
|
source[:HashPoint.HASH_LENGTH], resolver
|
||||||
),
|
),
|
||||||
FlowStandardFactory.of(FlowCoin.factory()).from_bytes(
|
FlowStandardFactory.of(FlowCoin.factory(), HashComparator(Fail())).from_bytes(
|
||||||
source[HashPoint.HASH_LENGTH:2 * HashPoint.HASH_LENGTH], resolver
|
source[HashPoint.HASH_LENGTH:2 * HashPoint.HASH_LENGTH], resolver
|
||||||
),
|
),
|
||||||
FlowStandardFactory.of(FlowCoin.factory()).from_bytes(
|
FlowStandardFactory.of(FlowCoin.factory(), HashComparator(Fail())).from_bytes(
|
||||||
source[2 * HashPoint.HASH_LENGTH:3 * HashPoint.HASH_LENGTH], resolver
|
source[2 * HashPoint.HASH_LENGTH:3 * HashPoint.HASH_LENGTH], resolver
|
||||||
),
|
),
|
||||||
FlowStandardFactory.of(KeyValueFactory(FlowCoin.factory(), FlowTransaction.factory()).loose()).from_bytes(
|
FlowStandardFactory.of(
|
||||||
|
KeyValue.f(FlowCoin.factory(), FlowTransaction.factory()),
|
||||||
|
KeyedComparator(HashComparator(Fail()))
|
||||||
|
).from_bytes(
|
||||||
source[3 * HashPoint.HASH_LENGTH:], resolver
|
source[3 * HashPoint.HASH_LENGTH:], resolver
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -152,7 +156,7 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
|||||||
async def _transaction_usedx(cls, transaction: FlowTransaction) -> Iterable[KeyValue[FlowCoin, FlowTransaction]]:
|
async def _transaction_usedx(cls, transaction: FlowTransaction) -> Iterable[KeyValue[FlowCoin, FlowTransaction]]:
|
||||||
assert isinstance(transaction, FlowTransaction)
|
assert isinstance(transaction, FlowTransaction)
|
||||||
return (
|
return (
|
||||||
KeyValue(HashPoint.of(coin), HashPoint.of(transaction))
|
KeyValue.of(coin, transaction)
|
||||||
for
|
for
|
||||||
coin
|
coin
|
||||||
in
|
in
|
||||||
@ -162,7 +166,9 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
|||||||
@classmethod
|
@classmethod
|
||||||
async def _make_minted(cls, transactions: Iterable[FlowTransaction]) -> FlowStandard[FlowCoin]:
|
async def _make_minted(cls, transactions: Iterable[FlowTransaction]) -> FlowStandard[FlowCoin]:
|
||||||
return await FlowStandardFactory.off(
|
return await FlowStandardFactory.off(
|
||||||
FlowCoin.factory(), itertools.chain(
|
FlowCoin.factory(),
|
||||||
|
HashComparator(Fail()),
|
||||||
|
itertools.chain(
|
||||||
*(await gather(*(cls._transaction_minted(transaction) for transaction in transactions)))
|
*(await gather(*(cls._transaction_minted(transaction) for transaction in transactions)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -170,9 +176,11 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
|||||||
@classmethod
|
@classmethod
|
||||||
async def _make_used(cls, transactions: Iterable[FlowTransaction]) -> FlowStandard[FlowCoin]:
|
async def _make_used(cls, transactions: Iterable[FlowTransaction]) -> FlowStandard[FlowCoin]:
|
||||||
return await FlowStandardFactory.off(
|
return await FlowStandardFactory.off(
|
||||||
FlowCoin.factory(), itertools.chain(
|
FlowCoin.factory(),
|
||||||
|
HashComparator(Fail()),
|
||||||
|
itertools.chain(
|
||||||
*(await gather(*(cls._transaction_used(transaction) for transaction in transactions)))
|
*(await gather(*(cls._transaction_used(transaction) for transaction in transactions)))
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -181,7 +189,9 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
|||||||
transactions: Iterable[FlowTransaction]
|
transactions: Iterable[FlowTransaction]
|
||||||
) -> FlowStandard[KeyValue[FlowCoin, FlowTransaction]]:
|
) -> FlowStandard[KeyValue[FlowCoin, FlowTransaction]]:
|
||||||
return await FlowStandardFactory.off(
|
return await FlowStandardFactory.off(
|
||||||
KeyValueFactory(FlowCoin.factory(), FlowTransaction.factory()).loose(), itertools.chain(
|
KeyValue.f(FlowCoin.factory(), FlowTransaction.factory()),
|
||||||
|
KeyedComparator(HashComparator(Fail())),
|
||||||
|
itertools.chain(
|
||||||
*(await gather(*(cls._transaction_usedx(transaction) for transaction in transactions)))
|
*(await gather(*(cls._transaction_usedx(transaction) for transaction in transactions)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -193,7 +203,7 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
|||||||
used: FlowStandard[FlowCoin]
|
used: FlowStandard[FlowCoin]
|
||||||
usedx: FlowStandard[KeyValue[FlowCoin, FlowTransaction]]
|
usedx: FlowStandard[KeyValue[FlowCoin, FlowTransaction]]
|
||||||
transactions_standard, minted, used, usedx = await gather(
|
transactions_standard, minted, used, usedx = await gather(
|
||||||
FlowStandardFactory.off(FlowTransaction.factory(), transactions),
|
FlowStandardFactory.off(FlowTransaction.factory(), HashComparator(Fail()), transactions),
|
||||||
cls._make_minted(transactions),
|
cls._make_minted(transactions),
|
||||||
cls._make_used(transactions),
|
cls._make_used(transactions),
|
||||||
cls._make_usedx(transactions),
|
cls._make_usedx(transactions),
|
||||||
@ -220,6 +230,20 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
|||||||
f'{tabulate(tab)})'
|
f'{tabulate(tab)})'
|
||||||
|
|
||||||
|
|
||||||
|
class UsedxMapper(Mapper[HashPoint[FlowCoin], HashPoint[KeyValue[FlowCoin, FlowTransaction]]]):
|
||||||
|
def __init__(self, transaction: HashPoint[FlowTransaction]):
|
||||||
|
assert isinstance(transaction, HashPoint)
|
||||||
|
self.transaction = transaction
|
||||||
|
|
||||||
|
async def map(self, element: HashPoint[FlowCoin]) -> HashPoint[KeyValue[FlowCoin, FlowTransaction]]:
|
||||||
|
return HashPoint.of(
|
||||||
|
await KeyValue.off(
|
||||||
|
element,
|
||||||
|
self.transaction
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TransactionVerification(
|
class TransactionVerification(
|
||||||
Verification[HashPoint[FlowTransaction]]
|
Verification[HashPoint[FlowTransaction]]
|
||||||
):
|
):
|
||||||
@ -236,17 +260,8 @@ class TransactionVerification(
|
|||||||
assert isinstance(reducer, Reducer)
|
assert isinstance(reducer, Reducer)
|
||||||
assert isinstance(transaction, HashPoint)
|
assert isinstance(transaction, HashPoint)
|
||||||
|
|
||||||
def usedx(coin: HashPoint[FlowCoin]) -> HashPoint[KeyValue[FlowCoin, FlowTransaction]]:
|
|
||||||
assert isinstance(coin, HashPoint)
|
|
||||||
return HashPoint.of(
|
|
||||||
KeyValue(
|
|
||||||
coin,
|
|
||||||
transaction
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
usedx_reducer: Reducer[HashPoint[KeyValue[FlowCoin, FlowTransaction]], bool] = MapReducer(
|
usedx_reducer: Reducer[HashPoint[KeyValue[FlowCoin, FlowTransaction]], bool] = MapReducer(
|
||||||
CallableMapper(usedx),
|
UsedxMapper(transaction),
|
||||||
reducer
|
reducer
|
||||||
)
|
)
|
||||||
assert isinstance(usedx_reducer, Reducer)
|
assert isinstance(usedx_reducer, Reducer)
|
||||||
@ -328,7 +343,7 @@ class UsedVerification(
|
|||||||
assert isinstance(element, HashPoint)
|
assert isinstance(element, HashPoint)
|
||||||
assert_true(
|
assert_true(
|
||||||
await self.cheque.usedx.contains(
|
await self.cheque.usedx.contains(
|
||||||
HashPoint.of(KeyValue(element, HashPoint.of(FlowTransaction.empty())))
|
HashPoint.of(await KeyValue.off(element, HashPoint.of(FlowTransaction.empty())))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
@ -34,7 +34,8 @@ class FlowStandard(
|
|||||||
|
|
||||||
def __factory__(self) -> RainbowFactory['FlowStandard[KeyT]']:
|
def __factory__(self) -> RainbowFactory['FlowStandard[KeyT]']:
|
||||||
return FlowStandardFactory(
|
return FlowStandardFactory(
|
||||||
self.protocolized.tree.reference.factory
|
self.protocolized.tree.reference.factory,
|
||||||
|
self.protocolized.creation.comparator
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, protocolized: BP):
|
def __init__(self, protocolized: BP):
|
||||||
@ -84,35 +85,41 @@ class FlowStandard(
|
|||||||
class FlowStandardFactory(RainbowFactory[FlowStandard[KeyT]], Generic[KeyT]):
|
class FlowStandardFactory(RainbowFactory[FlowStandard[KeyT]], Generic[KeyT]):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
factory: RainbowFactory[BinaryTree[KeyMetadata[KeyT, Integer]]]
|
factory: RainbowFactory[BinaryTree[KeyMetadata[KeyT, Integer]]],
|
||||||
|
comparator: Comparator[KeyT]
|
||||||
):
|
):
|
||||||
assert isinstance(factory, RainbowFactory)
|
assert isinstance(factory, RainbowFactory)
|
||||||
|
assert isinstance(comparator, Comparator)
|
||||||
self.factory = factory
|
self.factory = factory
|
||||||
|
self.comparator = comparator
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def of(cls, factory: RainbowFactory[KeyT]) -> 'FlowStandardFactory[KeyT]':
|
def of(cls, factory: RainbowFactory[KeyT], comparator: Comparator[KeyT]) -> 'FlowStandardFactory[KeyT]':
|
||||||
assert isinstance(factory, RainbowFactory)
|
assert isinstance(factory, RainbowFactory)
|
||||||
return FlowStandardFactory(
|
return FlowStandardFactory(
|
||||||
BinaryTreeFactory(KeyMetadataFactory(factory, Integer.factory()))
|
BinaryTreeFactory(KeyMetadataFactory(factory, Integer.factory())),
|
||||||
|
comparator
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def off(cls, factory: RainbowFactory[KeyT], keys: Iterable[KeyT]) -> 'FlowStandard[KeyT]':
|
async def off(
|
||||||
|
cls, factory: RainbowFactory[KeyT], comparator: Comparator[KeyT], keys: Iterable[KeyT]
|
||||||
|
) -> 'FlowStandard[KeyT]':
|
||||||
assert isinstance(factory, RainbowFactory)
|
assert isinstance(factory, RainbowFactory)
|
||||||
abt: ActiveBinaryTree[KeyT, Integer] = cls.empty(factory).protocolized.tree
|
abt: ActiveBinaryTree[KeyT, Integer] = cls.empty(factory, comparator).protocolized.tree
|
||||||
for key in keys:
|
for key in keys:
|
||||||
abt = await abt.add(HashPoint.of(key))
|
abt = await abt.add(HashPoint.of(key))
|
||||||
return FlowStandard(abt.protocolized())
|
return FlowStandard(abt.protocolized())
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def protocol(cls) -> BinaryBalancing[KeyT, Integer, ABT]:
|
def protocol(cls, comparator: Comparator[KeyT]) -> BinaryBalancing[KeyT, Integer, ABT]:
|
||||||
return AVL(HashComparator(Fail()))
|
return AVL(comparator)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def empty(cls, factory: RainbowFactory[KeyT]) -> 'FlowStandard[KeyT]':
|
def empty(cls, factory: RainbowFactory[KeyT], comparator: Comparator[KeyT]) -> 'FlowStandard[KeyT]':
|
||||||
assert isinstance(factory, RainbowFactory)
|
assert isinstance(factory, RainbowFactory)
|
||||||
return FlowStandard(
|
return FlowStandard(
|
||||||
ActiveBinaryTree.empty(cls.protocol(), factory).protocolized()
|
ActiveBinaryTree.empty(cls.protocol(comparator), factory).protocolized()
|
||||||
)
|
)
|
||||||
|
|
||||||
def from_bytes(self, source: bytes, resolver: HashResolver) -> FlowStandard[KeyT]:
|
def from_bytes(self, source: bytes, resolver: HashResolver) -> FlowStandard[KeyT]:
|
||||||
@ -120,7 +127,7 @@ class FlowStandardFactory(RainbowFactory[FlowStandard[KeyT]], Generic[KeyT]):
|
|||||||
assert isinstance(resolver, HashResolver)
|
assert isinstance(resolver, HashResolver)
|
||||||
return FlowStandard(
|
return FlowStandard(
|
||||||
ActiveBinaryTree(
|
ActiveBinaryTree(
|
||||||
self.protocol(),
|
self.protocol(self.comparator),
|
||||||
NullableReferenceFactory(self.factory).from_bytes(source, resolver)
|
NullableReferenceFactory(self.factory).from_bytes(source, resolver)
|
||||||
).protocolized()
|
).protocolized()
|
||||||
)
|
)
|
||||||
|
@ -3,6 +3,7 @@ from typing import Any, Iterable
|
|||||||
from nacl.signing import SigningKey
|
from nacl.signing import SigningKey
|
||||||
|
|
||||||
from rainbowadn.atomic import *
|
from rainbowadn.atomic import *
|
||||||
|
from rainbowadn.collection.comparison import *
|
||||||
from rainbowadn.collection.keyvalue import *
|
from rainbowadn.collection.keyvalue import *
|
||||||
from rainbowadn.core import *
|
from rainbowadn.core import *
|
||||||
from rainbowadn.flow.core import *
|
from rainbowadn.flow.core import *
|
||||||
@ -132,8 +133,12 @@ class FlowTransactionData(RecursiveMentionable, StaticMentionable):
|
|||||||
assert isinstance(resolver, HashResolver)
|
assert isinstance(resolver, HashResolver)
|
||||||
|
|
||||||
return cls(
|
return cls(
|
||||||
FlowStandardFactory.of(FlowCoin.factory()).from_bytes(source[:HashPoint.HASH_LENGTH], resolver),
|
FlowStandardFactory.of(
|
||||||
FlowStandardFactory.of(FlowCoinData.factory()).from_bytes(source[HashPoint.HASH_LENGTH:], resolver),
|
FlowCoin.factory(), HashComparator(Fail())
|
||||||
|
).from_bytes(source[:HashPoint.HASH_LENGTH], resolver),
|
||||||
|
FlowStandardFactory.of(
|
||||||
|
FlowCoinData.factory(), HashComparator(Fail())
|
||||||
|
).from_bytes(source[HashPoint.HASH_LENGTH:], resolver),
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _signature_verify(self, coin: FlowCoin, signature: Signature) -> bool:
|
async def _signature_verify(self, coin: FlowCoin, signature: Signature) -> bool:
|
||||||
@ -229,8 +234,8 @@ class FlowTransactionData(RecursiveMentionable, StaticMentionable):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def empty(cls) -> 'FlowTransactionData':
|
def empty(cls) -> 'FlowTransactionData':
|
||||||
return cls(
|
return cls(
|
||||||
FlowStandardFactory.empty(FlowCoin.factory()),
|
FlowStandardFactory.empty(FlowCoin.factory(), HashComparator(Fail())),
|
||||||
FlowStandardFactory.empty(FlowCoinData.factory()),
|
FlowStandardFactory.empty(FlowCoinData.factory(), HashComparator(Fail())),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -243,7 +248,7 @@ class CVMapper(Mapper[FlowCoin, bool]):
|
|||||||
assert isinstance(element, FlowCoin)
|
assert isinstance(element, FlowCoin)
|
||||||
assert_true(
|
assert_true(
|
||||||
await self.signatures.contains(
|
await self.signatures.contains(
|
||||||
HashPoint.of(KeyValue((await element.data.resolve()).owner, HashPoint.of(Signature.empty())))
|
HashPoint.of(await KeyValue.off((await element.data.resolve()).owner, HashPoint.of(Signature.empty())))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
@ -302,7 +307,10 @@ class FlowTransaction(RecursiveMentionable, StaticMentionable):
|
|||||||
assert isinstance(resolver, HashResolver)
|
assert isinstance(resolver, HashResolver)
|
||||||
return cls(
|
return cls(
|
||||||
ResolverOrigin(FlowTransactionData.factory(), source[:HashPoint.HASH_LENGTH], resolver).hash_point(),
|
ResolverOrigin(FlowTransactionData.factory(), source[:HashPoint.HASH_LENGTH], resolver).hash_point(),
|
||||||
FlowStandardFactory.of(KeyValueFactory(Subject.factory(), Signature.factory()).loose()).from_bytes(
|
FlowStandardFactory.of(
|
||||||
|
KeyValue.f(Subject.factory(), Signature.factory()),
|
||||||
|
KeyedComparator(HashComparator(Fail()))
|
||||||
|
).from_bytes(
|
||||||
source[HashPoint.HASH_LENGTH:], resolver
|
source[HashPoint.HASH_LENGTH:], resolver
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -339,7 +347,9 @@ class FlowTransaction(RecursiveMentionable, StaticMentionable):
|
|||||||
def empty(cls):
|
def empty(cls):
|
||||||
return cls(
|
return cls(
|
||||||
HashPoint.of(FlowTransactionData.empty()),
|
HashPoint.of(FlowTransactionData.empty()),
|
||||||
FlowStandardFactory.empty(KeyValueFactory(Subject.factory(), Signature.factory()).loose()),
|
FlowStandardFactory.empty(
|
||||||
|
KeyValue.f(Subject.factory(), Signature.factory()), KeyedComparator(HashComparator(Fail()))
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -352,8 +362,8 @@ class FlowTransaction(RecursiveMentionable, StaticMentionable):
|
|||||||
used_std: FlowStandard[FlowCoin]
|
used_std: FlowStandard[FlowCoin]
|
||||||
minted_std: FlowStandard[FlowCoinData]
|
minted_std: FlowStandard[FlowCoinData]
|
||||||
used_std, minted_std = await gather(
|
used_std, minted_std = await gather(
|
||||||
FlowStandardFactory.off(FlowCoin.factory(), used),
|
FlowStandardFactory.off(FlowCoin.factory(), HashComparator(Fail()), used),
|
||||||
FlowStandardFactory.off(FlowCoinData.factory(), minted),
|
FlowStandardFactory.off(FlowCoinData.factory(), HashComparator(Fail()), minted),
|
||||||
)
|
)
|
||||||
assert isinstance(used_std, FlowStandard)
|
assert isinstance(used_std, FlowStandard)
|
||||||
assert isinstance(minted_std, FlowStandard)
|
assert isinstance(minted_std, FlowStandard)
|
||||||
@ -362,9 +372,9 @@ class FlowTransaction(RecursiveMentionable, StaticMentionable):
|
|||||||
minted_std,
|
minted_std,
|
||||||
)
|
)
|
||||||
signatures: list[KeyValue[Subject, Signature]] = [
|
signatures: list[KeyValue[Subject, Signature]] = [
|
||||||
KeyValue(
|
KeyValue.of(
|
||||||
HashPoint.of(Subject(signing_key.verify_key)),
|
Subject(signing_key.verify_key),
|
||||||
HashPoint.of(Signature.sign(signing_key, transaction_data.hash_point)),
|
Signature.sign(signing_key, transaction_data.hash_point),
|
||||||
)
|
)
|
||||||
for
|
for
|
||||||
signing_key
|
signing_key
|
||||||
@ -373,5 +383,7 @@ class FlowTransaction(RecursiveMentionable, StaticMentionable):
|
|||||||
]
|
]
|
||||||
return cls(
|
return cls(
|
||||||
HashPoint.of(transaction_data),
|
HashPoint.of(transaction_data),
|
||||||
await FlowStandardFactory.off(KeyValueFactory(Subject.factory(), Signature.factory()).loose(), signatures)
|
await FlowStandardFactory.off(
|
||||||
|
KeyValue.f(Subject.factory(), Signature.factory()), KeyedComparator(HashComparator(Fail())), signatures
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
__all__ = (
|
__all__ = (
|
||||||
'Measure',
|
'Measure',
|
||||||
'Terminated', 'Terminate',
|
'Terminated', 'Terminate',
|
||||||
|
'ClassReport',
|
||||||
'Concurrency',
|
'Concurrency',
|
||||||
'Counter',
|
'Counter',
|
||||||
'EntryExit',
|
'EntryExit',
|
||||||
@ -9,6 +10,7 @@ __all__ = (
|
|||||||
|
|
||||||
from ._measure import Measure
|
from ._measure import Measure
|
||||||
from ._terminate import Terminate, Terminated
|
from ._terminate import Terminate, Terminated
|
||||||
|
from .classreport import ClassReport
|
||||||
from .concurrency import Concurrency
|
from .concurrency import Concurrency
|
||||||
from .counter import Counter
|
from .counter import Counter
|
||||||
from .entryexit import EntryExit
|
from .entryexit import EntryExit
|
||||||
|
40
rainbowadn/instrument/classreport.py
Normal file
40
rainbowadn/instrument/classreport.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
from rainbowadn.core import *
|
||||||
|
|
||||||
|
__all__ = ('ClassReport',)
|
||||||
|
|
||||||
|
|
||||||
|
class ClassReport:
|
||||||
|
def __init__(self):
|
||||||
|
self.report: set[tuple[str, bytes, bytes]] = set()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _tuple(cls, mentionable: Mentionable) -> tuple[str, bytes, bytes]:
|
||||||
|
return type(mentionable).__name__, bytes(HashPoint.of(mentionable)), bytes(mentionable)
|
||||||
|
|
||||||
|
def _cointains(self, mentionable: Mentionable) -> bool:
|
||||||
|
return self._tuple(mentionable) in self.report
|
||||||
|
|
||||||
|
async def _recurse(self, recursive: RecursiveMentionable):
|
||||||
|
for mentioned in await gather(*map(HashPoint.resolve, recursive.points())):
|
||||||
|
await self.walk(mentioned)
|
||||||
|
|
||||||
|
def _contain(self, mentionable: Mentionable) -> None:
|
||||||
|
self.report.add(self._tuple(mentionable))
|
||||||
|
|
||||||
|
async def _save(self, mentionable: Mentionable):
|
||||||
|
self._contain(mentionable)
|
||||||
|
if isinstance(mentionable, RecursiveMentionable):
|
||||||
|
await self._recurse(mentionable)
|
||||||
|
|
||||||
|
async def walk(self, mentionable: Mentionable):
|
||||||
|
if self._cointains(mentionable):
|
||||||
|
return
|
||||||
|
await self._save(mentionable)
|
||||||
|
|
||||||
|
def format(self) -> str:
|
||||||
|
s = StringIO()
|
||||||
|
for type_, point, bytes_ in sorted(self.report):
|
||||||
|
s.write(f'{type_:<32}:{point.hex()}:{bytes_.hex()}\n')
|
||||||
|
return s.getvalue()
|
@ -3,12 +3,13 @@ import random
|
|||||||
from contextlib import ExitStack
|
from contextlib import ExitStack
|
||||||
from typing import Any, Callable, Coroutine
|
from typing import Any, Callable, Coroutine
|
||||||
|
|
||||||
from nacl.signing import SigningKey
|
from nacl.signing import SigningKey, VerifyKey
|
||||||
|
|
||||||
from plot import *
|
from plot import *
|
||||||
from rainbowadn.collection.trees.binary import *
|
from rainbowadn.collection.trees.binary import *
|
||||||
from rainbowadn.core import *
|
from rainbowadn.core import *
|
||||||
from rainbowadn.flow13 import *
|
from rainbowadn.flow13 import *
|
||||||
|
from rainbowadn.flow13 import FlowCoin
|
||||||
from rainbowadn.instrument import *
|
from rainbowadn.instrument import *
|
||||||
from rainbowadn.testing.resolvers import *
|
from rainbowadn.testing.resolvers import *
|
||||||
from rainbowadn.v13 import *
|
from rainbowadn.v13 import *
|
||||||
@ -25,6 +26,42 @@ def get_instrumentations() -> list[Instrumentation]:
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
minted: set[HashPoint[FlowCoin]] = set()
|
||||||
|
reverse: dict[VerifyKey, SigningKey] = {}
|
||||||
|
|
||||||
|
|
||||||
|
def _generate_subject() -> Subject:
|
||||||
|
signing_key = SigningKey.generate()
|
||||||
|
verify_key = signing_key.verify_key
|
||||||
|
reverse[verify_key] = signing_key
|
||||||
|
return Subject(verify_key)
|
||||||
|
|
||||||
|
|
||||||
|
async def _generate_transaction(
|
||||||
|
subjects_min: int,
|
||||||
|
subjects_max: int,
|
||||||
|
):
|
||||||
|
in_coins: list[FlowCoin] = []
|
||||||
|
keys: list[SigningKey] = []
|
||||||
|
for _ in range(random.randint(subjects_min, subjects_max)):
|
||||||
|
if not minted:
|
||||||
|
break
|
||||||
|
coin = await minted.pop().resolve()
|
||||||
|
in_coins.append(coin)
|
||||||
|
keys.append(reverse[(await coin.owner_resolved()).verify_key])
|
||||||
|
transaction = await FlowTransaction.make(
|
||||||
|
in_coins,
|
||||||
|
[
|
||||||
|
FlowCoinData.of(_generate_subject(), 0)
|
||||||
|
for _ in range(random.randint(subjects_min, subjects_max))
|
||||||
|
],
|
||||||
|
keys
|
||||||
|
)
|
||||||
|
for coinhp in await (await transaction.minted_reducer()).reduce(FlowIterate([])):
|
||||||
|
minted.add(coinhp)
|
||||||
|
return transaction
|
||||||
|
|
||||||
|
|
||||||
async def _generate(
|
async def _generate(
|
||||||
blocks: int,
|
blocks: int,
|
||||||
subjects_min: int,
|
subjects_min: int,
|
||||||
@ -37,14 +74,7 @@ async def _generate(
|
|||||||
bank = await bank.add(
|
bank = await bank.add(
|
||||||
await FlowCheque.make(
|
await FlowCheque.make(
|
||||||
[
|
[
|
||||||
await FlowTransaction.make(
|
await _generate_transaction(subjects_min, subjects_max)
|
||||||
[],
|
|
||||||
[
|
|
||||||
FlowCoinData.of(Subject(SigningKey.generate().verify_key), 0)
|
|
||||||
for _ in range(random.randint(subjects_min, subjects_max))
|
|
||||||
],
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
for _ in range(random.randint(transactions_min, transactions_max))
|
for _ in range(random.randint(transactions_min, transactions_max))
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -80,6 +110,14 @@ async def _process(bank: BankBlock) -> None:
|
|||||||
print('measured', *(f'{t:.3f}' for t in measurement.log))
|
print('measured', *(f'{t:.3f}' for t in measurement.log))
|
||||||
|
|
||||||
|
|
||||||
|
async def _report(bank: BankBlock):
|
||||||
|
with open('trace/latest-report.txt', 'w') as file:
|
||||||
|
report = ClassReport()
|
||||||
|
await report.walk(bank.reference)
|
||||||
|
file.write(report.format())
|
||||||
|
print('reported')
|
||||||
|
|
||||||
|
|
||||||
async def _trace(params):
|
async def _trace(params):
|
||||||
set_gather_linear()
|
set_gather_linear()
|
||||||
bank = await _generate(
|
bank = await _generate(
|
||||||
@ -87,6 +125,7 @@ async def _trace(params):
|
|||||||
*params['subjects'],
|
*params['subjects'],
|
||||||
*params['transactions'],
|
*params['transactions'],
|
||||||
)
|
)
|
||||||
|
await _report(bank)
|
||||||
await _process(bank)
|
await _process(bank)
|
||||||
bank = await _migrate(bank, params)
|
bank = await _migrate(bank, params)
|
||||||
set_gather_asyncio()
|
set_gather_asyncio()
|
||||||
@ -108,9 +147,8 @@ async def trace(params):
|
|||||||
print('plotted')
|
print('plotted')
|
||||||
|
|
||||||
|
|
||||||
preset_long = dict(blocks=64, subjects=(8, 16), transactions=(8, 16), caching=True, delay=.35)
|
preset_long = dict(blocks=64, subjects=(4, 8), transactions=(8, 16), caching=True, delay=.5)
|
||||||
preset_short = dict(blocks=16, subjects=(8, 16), transactions=(8, 16), caching=True, delay=.35)
|
preset_short = dict(blocks=16, subjects=(4, 8), transactions=(8, 16), caching=True, delay=.5)
|
||||||
preset_old = dict(blocks=16, subjects=(8, 15), transactions=(8, 15), caching=False, delay=.35)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
asyncio.run(
|
asyncio.run(
|
||||||
|
Loading…
Reference in New Issue
Block a user