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.inlining import *
|
||||
from .keyed import *
|
||||
|
||||
__all__ = ('KeyValue', 'KeyValueFactory',)
|
||||
__all__ = ('KeyValue',)
|
||||
|
||||
KVKeyType = TypeVar('KVKeyType')
|
||||
KVValueType = TypeVar('KVValueType')
|
||||
|
||||
|
||||
class KeyValue(Keyed[KVKeyType], Generic[KVKeyType, KVValueType]):
|
||||
def __init__(self, key: HashPoint[KVKeyType], value: HashPoint[KVValueType]):
|
||||
class KeyValue(Keyed[KVKeyType], IAuto, Generic[KVKeyType, 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(value, HashPoint)
|
||||
super().__init__(key)
|
||||
self.value = value
|
||||
return await cls.from_hashpoints(key, value)
|
||||
|
||||
def points(self) -> Iterable[HashPoint]:
|
||||
return [self.key, self.value]
|
||||
@classmethod
|
||||
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):
|
||||
return bytes(self.key) + bytes(self.value)
|
||||
|
||||
def __factory__(self) -> RainbowFactory['KeyValue[KVKeyType, KVValueType]']:
|
||||
return KeyValueFactory(self.key.factory, self.value.factory)
|
||||
|
||||
async def str(self, tab: int) -> str:
|
||||
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
|
||||
@classmethod
|
||||
def f(
|
||||
cls, f0: RainbowFactory[KVKeyType], f1: RainbowFactory[KVValueType]
|
||||
) -> RainbowFactory['KeyValue[KVKeyType, KVValueType]']:
|
||||
assert isinstance(f0, RainbowFactory)
|
||||
assert isinstance(f1, RainbowFactory)
|
||||
return cls.factory(f0, f1)
|
||||
|
@ -42,6 +42,9 @@ class HashPoint(Generic[Mentioned]):
|
||||
assert isinstance(source, bytes)
|
||||
return _hash(source)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.point)
|
||||
|
||||
@classmethod
|
||||
def bytes_of_mentioned(cls, mentioned: Mentionable) -> bytes:
|
||||
assert isinstance(mentioned, Mentionable)
|
||||
|
@ -1,5 +1,6 @@
|
||||
from typing import Iterable
|
||||
|
||||
from rainbowadn.collection.comparison import *
|
||||
from rainbowadn.core import *
|
||||
from ._flowstandard import *
|
||||
from ._flowtransaction import *
|
||||
@ -11,10 +12,10 @@ class FlowBank(StaticMentionable, RecursiveMentionable):
|
||||
@classmethod
|
||||
def from_bytes(cls, source: bytes, resolver: HashResolver) -> 'FlowBank':
|
||||
return FlowBank(
|
||||
FlowStandardFactory.of(FlowCoin.factory()).from_bytes(
|
||||
FlowStandardFactory.of(FlowCoin.factory(), HashComparator(Fail())).from_bytes(
|
||||
source[:HashPoint.HASH_LENGTH], resolver
|
||||
),
|
||||
FlowStandardFactory.of(FlowCoin.factory()).from_bytes(
|
||||
FlowStandardFactory.of(FlowCoin.factory(), HashComparator(Fail())).from_bytes(
|
||||
source[HashPoint.HASH_LENGTH:], resolver
|
||||
),
|
||||
)
|
||||
@ -38,8 +39,8 @@ class FlowBank(StaticMentionable, RecursiveMentionable):
|
||||
@classmethod
|
||||
def empty(cls) -> 'FlowBank':
|
||||
return FlowBank(
|
||||
FlowStandardFactory.empty(FlowCoin.factory()),
|
||||
FlowStandardFactory.empty(FlowCoin.factory()),
|
||||
FlowStandardFactory.empty(FlowCoin.factory(), HashComparator(Fail())),
|
||||
FlowStandardFactory.empty(FlowCoin.factory(), HashComparator(Fail())),
|
||||
)
|
||||
|
||||
async def str(self, tab: int) -> str:
|
||||
|
@ -1,5 +1,6 @@
|
||||
from typing import Generic, Iterable, TypeAlias, TypeVar
|
||||
|
||||
from rainbowadn.collection.comparison import *
|
||||
from rainbowadn.core import *
|
||||
from rainbowadn.flow.verification.core import *
|
||||
from rainbowadn.nullability import *
|
||||
@ -51,7 +52,7 @@ class FlowBlock(Generic[LinkT], RecursiveMentionable):
|
||||
@classmethod
|
||||
async def outer_of(cls, factory: RainbowFactory[LinkT], reference: NullableReference[FBL]) -> Index:
|
||||
if reference.null():
|
||||
return FlowStandardFactory.empty(FlowBlockFactory(factory))
|
||||
return FlowStandardFactory.empty(FlowBlockFactory(factory), HashComparator(Fail()))
|
||||
else:
|
||||
return await (await reference.resolve()).outer()
|
||||
|
||||
@ -102,7 +103,9 @@ class FlowBlockFactory(RainbowFactory[FBL], Generic[LinkT]):
|
||||
assert isinstance(resolver, HashResolver)
|
||||
return FlowBlock(
|
||||
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(),
|
||||
)
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import itertools
|
||||
from typing import Iterable
|
||||
|
||||
from rainbowadn.collection.comparison import *
|
||||
from rainbowadn.collection.keyvalue import *
|
||||
from rainbowadn.core import *
|
||||
from rainbowadn.flow.core import *
|
||||
@ -29,16 +30,19 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
||||
@classmethod
|
||||
def from_bytes(cls, source: bytes, resolver: HashResolver) -> 'FlowCheque':
|
||||
return FlowCheque(
|
||||
FlowStandardFactory.of(FlowTransaction.factory()).from_bytes(
|
||||
FlowStandardFactory.of(FlowTransaction.factory(), HashComparator(Fail())).from_bytes(
|
||||
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
|
||||
),
|
||||
FlowStandardFactory.of(FlowCoin.factory()).from_bytes(
|
||||
FlowStandardFactory.of(FlowCoin.factory(), HashComparator(Fail())).from_bytes(
|
||||
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
|
||||
),
|
||||
)
|
||||
@ -152,7 +156,7 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
||||
async def _transaction_usedx(cls, transaction: FlowTransaction) -> Iterable[KeyValue[FlowCoin, FlowTransaction]]:
|
||||
assert isinstance(transaction, FlowTransaction)
|
||||
return (
|
||||
KeyValue(HashPoint.of(coin), HashPoint.of(transaction))
|
||||
KeyValue.of(coin, transaction)
|
||||
for
|
||||
coin
|
||||
in
|
||||
@ -162,7 +166,9 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
||||
@classmethod
|
||||
async def _make_minted(cls, transactions: Iterable[FlowTransaction]) -> FlowStandard[FlowCoin]:
|
||||
return await FlowStandardFactory.off(
|
||||
FlowCoin.factory(), itertools.chain(
|
||||
FlowCoin.factory(),
|
||||
HashComparator(Fail()),
|
||||
itertools.chain(
|
||||
*(await gather(*(cls._transaction_minted(transaction) for transaction in transactions)))
|
||||
)
|
||||
)
|
||||
@ -170,9 +176,11 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
||||
@classmethod
|
||||
async def _make_used(cls, transactions: Iterable[FlowTransaction]) -> FlowStandard[FlowCoin]:
|
||||
return await FlowStandardFactory.off(
|
||||
FlowCoin.factory(), itertools.chain(
|
||||
FlowCoin.factory(),
|
||||
HashComparator(Fail()),
|
||||
itertools.chain(
|
||||
*(await gather(*(cls._transaction_used(transaction) for transaction in transactions)))
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -181,7 +189,9 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
||||
transactions: Iterable[FlowTransaction]
|
||||
) -> FlowStandard[KeyValue[FlowCoin, FlowTransaction]]:
|
||||
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)))
|
||||
)
|
||||
)
|
||||
@ -193,7 +203,7 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
||||
used: FlowStandard[FlowCoin]
|
||||
usedx: FlowStandard[KeyValue[FlowCoin, FlowTransaction]]
|
||||
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_used(transactions),
|
||||
cls._make_usedx(transactions),
|
||||
@ -220,6 +230,20 @@ class FlowCheque(StaticMentionable, RecursiveMentionable):
|
||||
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(
|
||||
Verification[HashPoint[FlowTransaction]]
|
||||
):
|
||||
@ -236,17 +260,8 @@ class TransactionVerification(
|
||||
assert isinstance(reducer, Reducer)
|
||||
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(
|
||||
CallableMapper(usedx),
|
||||
UsedxMapper(transaction),
|
||||
reducer
|
||||
)
|
||||
assert isinstance(usedx_reducer, Reducer)
|
||||
@ -328,7 +343,7 @@ class UsedVerification(
|
||||
assert isinstance(element, HashPoint)
|
||||
assert_true(
|
||||
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
|
||||
|
@ -34,7 +34,8 @@ class FlowStandard(
|
||||
|
||||
def __factory__(self) -> RainbowFactory['FlowStandard[KeyT]']:
|
||||
return FlowStandardFactory(
|
||||
self.protocolized.tree.reference.factory
|
||||
self.protocolized.tree.reference.factory,
|
||||
self.protocolized.creation.comparator
|
||||
)
|
||||
|
||||
def __init__(self, protocolized: BP):
|
||||
@ -84,35 +85,41 @@ class FlowStandard(
|
||||
class FlowStandardFactory(RainbowFactory[FlowStandard[KeyT]], Generic[KeyT]):
|
||||
def __init__(
|
||||
self,
|
||||
factory: RainbowFactory[BinaryTree[KeyMetadata[KeyT, Integer]]]
|
||||
factory: RainbowFactory[BinaryTree[KeyMetadata[KeyT, Integer]]],
|
||||
comparator: Comparator[KeyT]
|
||||
):
|
||||
assert isinstance(factory, RainbowFactory)
|
||||
assert isinstance(comparator, Comparator)
|
||||
self.factory = factory
|
||||
self.comparator = comparator
|
||||
|
||||
@classmethod
|
||||
def of(cls, factory: RainbowFactory[KeyT]) -> 'FlowStandardFactory[KeyT]':
|
||||
def of(cls, factory: RainbowFactory[KeyT], comparator: Comparator[KeyT]) -> 'FlowStandardFactory[KeyT]':
|
||||
assert isinstance(factory, RainbowFactory)
|
||||
return FlowStandardFactory(
|
||||
BinaryTreeFactory(KeyMetadataFactory(factory, Integer.factory()))
|
||||
BinaryTreeFactory(KeyMetadataFactory(factory, Integer.factory())),
|
||||
comparator
|
||||
)
|
||||
|
||||
@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)
|
||||
abt: ActiveBinaryTree[KeyT, Integer] = cls.empty(factory).protocolized.tree
|
||||
abt: ActiveBinaryTree[KeyT, Integer] = cls.empty(factory, comparator).protocolized.tree
|
||||
for key in keys:
|
||||
abt = await abt.add(HashPoint.of(key))
|
||||
return FlowStandard(abt.protocolized())
|
||||
|
||||
@classmethod
|
||||
def protocol(cls) -> BinaryBalancing[KeyT, Integer, ABT]:
|
||||
return AVL(HashComparator(Fail()))
|
||||
def protocol(cls, comparator: Comparator[KeyT]) -> BinaryBalancing[KeyT, Integer, ABT]:
|
||||
return AVL(comparator)
|
||||
|
||||
@classmethod
|
||||
def empty(cls, factory: RainbowFactory[KeyT]) -> 'FlowStandard[KeyT]':
|
||||
def empty(cls, factory: RainbowFactory[KeyT], comparator: Comparator[KeyT]) -> 'FlowStandard[KeyT]':
|
||||
assert isinstance(factory, RainbowFactory)
|
||||
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]:
|
||||
@ -120,7 +127,7 @@ class FlowStandardFactory(RainbowFactory[FlowStandard[KeyT]], Generic[KeyT]):
|
||||
assert isinstance(resolver, HashResolver)
|
||||
return FlowStandard(
|
||||
ActiveBinaryTree(
|
||||
self.protocol(),
|
||||
self.protocol(self.comparator),
|
||||
NullableReferenceFactory(self.factory).from_bytes(source, resolver)
|
||||
).protocolized()
|
||||
)
|
||||
|
@ -3,6 +3,7 @@ from typing import Any, Iterable
|
||||
from nacl.signing import SigningKey
|
||||
|
||||
from rainbowadn.atomic import *
|
||||
from rainbowadn.collection.comparison import *
|
||||
from rainbowadn.collection.keyvalue import *
|
||||
from rainbowadn.core import *
|
||||
from rainbowadn.flow.core import *
|
||||
@ -132,8 +133,12 @@ class FlowTransactionData(RecursiveMentionable, StaticMentionable):
|
||||
assert isinstance(resolver, HashResolver)
|
||||
|
||||
return cls(
|
||||
FlowStandardFactory.of(FlowCoin.factory()).from_bytes(source[:HashPoint.HASH_LENGTH], resolver),
|
||||
FlowStandardFactory.of(FlowCoinData.factory()).from_bytes(source[HashPoint.HASH_LENGTH:], resolver),
|
||||
FlowStandardFactory.of(
|
||||
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:
|
||||
@ -229,8 +234,8 @@ class FlowTransactionData(RecursiveMentionable, StaticMentionable):
|
||||
@classmethod
|
||||
def empty(cls) -> 'FlowTransactionData':
|
||||
return cls(
|
||||
FlowStandardFactory.empty(FlowCoin.factory()),
|
||||
FlowStandardFactory.empty(FlowCoinData.factory()),
|
||||
FlowStandardFactory.empty(FlowCoin.factory(), HashComparator(Fail())),
|
||||
FlowStandardFactory.empty(FlowCoinData.factory(), HashComparator(Fail())),
|
||||
)
|
||||
|
||||
|
||||
@ -243,7 +248,7 @@ class CVMapper(Mapper[FlowCoin, bool]):
|
||||
assert isinstance(element, FlowCoin)
|
||||
assert_true(
|
||||
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
|
||||
@ -302,7 +307,10 @@ class FlowTransaction(RecursiveMentionable, StaticMentionable):
|
||||
assert isinstance(resolver, HashResolver)
|
||||
return cls(
|
||||
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
|
||||
),
|
||||
)
|
||||
@ -339,7 +347,9 @@ class FlowTransaction(RecursiveMentionable, StaticMentionable):
|
||||
def empty(cls):
|
||||
return cls(
|
||||
HashPoint.of(FlowTransactionData.empty()),
|
||||
FlowStandardFactory.empty(KeyValueFactory(Subject.factory(), Signature.factory()).loose()),
|
||||
FlowStandardFactory.empty(
|
||||
KeyValue.f(Subject.factory(), Signature.factory()), KeyedComparator(HashComparator(Fail()))
|
||||
),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -352,8 +362,8 @@ class FlowTransaction(RecursiveMentionable, StaticMentionable):
|
||||
used_std: FlowStandard[FlowCoin]
|
||||
minted_std: FlowStandard[FlowCoinData]
|
||||
used_std, minted_std = await gather(
|
||||
FlowStandardFactory.off(FlowCoin.factory(), used),
|
||||
FlowStandardFactory.off(FlowCoinData.factory(), minted),
|
||||
FlowStandardFactory.off(FlowCoin.factory(), HashComparator(Fail()), used),
|
||||
FlowStandardFactory.off(FlowCoinData.factory(), HashComparator(Fail()), minted),
|
||||
)
|
||||
assert isinstance(used_std, FlowStandard)
|
||||
assert isinstance(minted_std, FlowStandard)
|
||||
@ -362,9 +372,9 @@ class FlowTransaction(RecursiveMentionable, StaticMentionable):
|
||||
minted_std,
|
||||
)
|
||||
signatures: list[KeyValue[Subject, Signature]] = [
|
||||
KeyValue(
|
||||
HashPoint.of(Subject(signing_key.verify_key)),
|
||||
HashPoint.of(Signature.sign(signing_key, transaction_data.hash_point)),
|
||||
KeyValue.of(
|
||||
Subject(signing_key.verify_key),
|
||||
Signature.sign(signing_key, transaction_data.hash_point),
|
||||
)
|
||||
for
|
||||
signing_key
|
||||
@ -373,5 +383,7 @@ class FlowTransaction(RecursiveMentionable, StaticMentionable):
|
||||
]
|
||||
return cls(
|
||||
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__ = (
|
||||
'Measure',
|
||||
'Terminated', 'Terminate',
|
||||
'ClassReport',
|
||||
'Concurrency',
|
||||
'Counter',
|
||||
'EntryExit',
|
||||
@ -9,6 +10,7 @@ __all__ = (
|
||||
|
||||
from ._measure import Measure
|
||||
from ._terminate import Terminate, Terminated
|
||||
from .classreport import ClassReport
|
||||
from .concurrency import Concurrency
|
||||
from .counter import Counter
|
||||
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 typing import Any, Callable, Coroutine
|
||||
|
||||
from nacl.signing import SigningKey
|
||||
from nacl.signing import SigningKey, VerifyKey
|
||||
|
||||
from plot import *
|
||||
from rainbowadn.collection.trees.binary import *
|
||||
from rainbowadn.core import *
|
||||
from rainbowadn.flow13 import *
|
||||
from rainbowadn.flow13 import FlowCoin
|
||||
from rainbowadn.instrument import *
|
||||
from rainbowadn.testing.resolvers 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(
|
||||
blocks: int,
|
||||
subjects_min: int,
|
||||
@ -37,14 +74,7 @@ async def _generate(
|
||||
bank = await bank.add(
|
||||
await FlowCheque.make(
|
||||
[
|
||||
await FlowTransaction.make(
|
||||
[],
|
||||
[
|
||||
FlowCoinData.of(Subject(SigningKey.generate().verify_key), 0)
|
||||
for _ in range(random.randint(subjects_min, subjects_max))
|
||||
],
|
||||
[]
|
||||
)
|
||||
await _generate_transaction(subjects_min, subjects_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))
|
||||
|
||||
|
||||
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):
|
||||
set_gather_linear()
|
||||
bank = await _generate(
|
||||
@ -87,6 +125,7 @@ async def _trace(params):
|
||||
*params['subjects'],
|
||||
*params['transactions'],
|
||||
)
|
||||
await _report(bank)
|
||||
await _process(bank)
|
||||
bank = await _migrate(bank, params)
|
||||
set_gather_asyncio()
|
||||
@ -108,9 +147,8 @@ async def trace(params):
|
||||
print('plotted')
|
||||
|
||||
|
||||
preset_long = dict(blocks=64, subjects=(8, 16), transactions=(8, 16), caching=True, delay=.35)
|
||||
preset_short = dict(blocks=16, subjects=(8, 16), transactions=(8, 16), caching=True, delay=.35)
|
||||
preset_old = dict(blocks=16, subjects=(8, 15), transactions=(8, 15), caching=False, delay=.35)
|
||||
preset_long = dict(blocks=64, subjects=(4, 8), transactions=(8, 16), caching=True, delay=.5)
|
||||
preset_short = dict(blocks=16, subjects=(4, 8), transactions=(8, 16), caching=True, delay=.5)
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(
|
||||
|
Loading…
Reference in New Issue
Block a user