add missing asserts + trace/plot + optimize avl (+ remove fsplit) + more instrumentation
This commit is contained in:
parent
001c8e1930
commit
d86609d8b3
1
.gitignore
vendored
1
.gitignore
vendored
@ -211,3 +211,4 @@ fabric.properties
|
|||||||
# Android studio 3.1+ serialized cache file
|
# Android studio 3.1+ serialized cache file
|
||||||
.idea/caches/build_file_checksums.ser
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
/trace/
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/trace" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
97
plot.py
97
plot.py
@ -1,88 +1,31 @@
|
|||||||
import asyncio
|
import json
|
||||||
import random
|
|
||||||
|
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from nacl.signing import SigningKey
|
|
||||||
|
|
||||||
from rainbowadn.chain import *
|
|
||||||
from rainbowadn.core import *
|
|
||||||
from rainbowadn.nullability import *
|
|
||||||
from rainbowadn.testing.delayedresolver import DelayedResolver
|
|
||||||
from rainbowadn.testing.dictresolver import DictResolver
|
|
||||||
from rainbowadn.testing.instrumentation import Concurrency
|
|
||||||
from rainbowadn.v13 import *
|
|
||||||
|
|
||||||
plt.rcParams['figure.figsize'] = [12, 6]
|
def plottable(log: list[tuple[float, int]]):
|
||||||
|
if log:
|
||||||
|
return np.array(log).transpose()
|
||||||
|
else:
|
||||||
|
return np.array([[], []])
|
||||||
|
|
||||||
|
|
||||||
|
def plot():
|
||||||
|
plt.rcParams['figure.figsize'] = [16, 9]
|
||||||
plt.style.use("dark_background")
|
plt.style.use("dark_background")
|
||||||
|
plt.subplots_adjust(left=0.03, right=0.99, top=0.99, bottom=0.05)
|
||||||
|
|
||||||
plt.subplots_adjust(left=0.05, right=0.99, top=0.99, bottom=0.1)
|
with open('trace/latest.json') as file:
|
||||||
|
jsonified = json.load(file)
|
||||||
|
if (log := jsonified.get('DelayedResolver:sleep:concurrency')) is not None:
|
||||||
def get_dr() -> ExtendableResolver:
|
plt.plot(*plottable(log))
|
||||||
dr = DictResolver()
|
if (log := jsonified.get('ActiveBinaryTree:add:entry')) is not None:
|
||||||
dr = DelayedResolver(dr, lambda: random.uniform(0.200, 0.500))
|
plt.scatter(*plottable(log), c='tomato', zorder=100, s=.5)
|
||||||
return dr
|
if (log := jsonified.get('ActiveBinaryTree:add:exit')) is not None:
|
||||||
|
plt.scatter(*plottable(log), c='gold', zorder=99, s=.5)
|
||||||
|
|
||||||
def plot(instrumentation: Concurrency):
|
|
||||||
plt.plot(*np.array(instrumentation.logs).transpose())
|
|
||||||
|
|
||||||
|
|
||||||
async def plot_every_minute(instrumentation: Concurrency):
|
|
||||||
while True:
|
|
||||||
await asyncio.sleep(60)
|
|
||||||
plot(instrumentation)
|
|
||||||
plt.show()
|
|
||||||
plt.clf()
|
|
||||||
plt.subplots_adjust(left=0.05, right=0.99, top=0.99, bottom=0.1)
|
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
|
||||||
set_gather_asyncio()
|
|
||||||
bank: BankChain = BankChain.empty(ReductionChainMetaFactory().loose())
|
|
||||||
key_0 = SigningKey.generate()
|
|
||||||
transaction_0 = Transaction.make(
|
|
||||||
[],
|
|
||||||
[CoinData.of(Subject(key_0.verify_key), 100_000)],
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
coin_0, coin_1 = await transaction_0.coins(MINT_CONST, NotNull(HashPoint.of(Subject(key_0.verify_key))))
|
|
||||||
bank = await bank.adds(
|
|
||||||
[
|
|
||||||
transaction_0,
|
|
||||||
Transaction.make(
|
|
||||||
[coin_1],
|
|
||||||
[CoinData.of(Subject(SigningKey.generate().verify_key), 10_000)],
|
|
||||||
[key_0]
|
|
||||||
),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
for _ in range(16):
|
|
||||||
bank = await bank.adds(
|
|
||||||
[
|
|
||||||
Transaction.make(
|
|
||||||
[],
|
|
||||||
[CoinData.of(Subject(SigningKey.generate().verify_key), 0)] * 16,
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
for _ in range(16)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
print('built')
|
|
||||||
assert_true(await bank.verify())
|
|
||||||
bank = BankChain.from_reference(
|
|
||||||
ReductionChainMetaFactory(), await get_dr().migrate_resolved(bank.reference)
|
|
||||||
)
|
|
||||||
print('saved')
|
|
||||||
set_gather_asyncio()
|
|
||||||
with Concurrency(DelayedResolver, 'sleep') as sleeps:
|
|
||||||
# task = asyncio.create_task(plot_every_minute(sleeps))
|
|
||||||
assert_true(await bank.verify())
|
|
||||||
# task.cancel()
|
|
||||||
plot(sleeps)
|
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
asyncio.run(main())
|
if __name__ == '__main__':
|
||||||
|
plot()
|
||||||
|
@ -42,6 +42,9 @@ class Block(RecursiveMentionable, Generic[HeaderType, StateType]):
|
|||||||
hash_point_format(self.header, tab + 1),
|
hash_point_format(self.header, tab + 1),
|
||||||
hash_point_format(self.state, tab + 1),
|
hash_point_format(self.state, tab + 1),
|
||||||
)
|
)
|
||||||
|
assert isinstance(previous_str, str)
|
||||||
|
assert isinstance(header_str, str)
|
||||||
|
assert isinstance(state_str, str)
|
||||||
return f'{previous_str}' \
|
return f'{previous_str}' \
|
||||||
f'{tabulate(tab)}(' \
|
f'{tabulate(tab)}(' \
|
||||||
f'{tabulate(tab + 1)}block' \
|
f'{tabulate(tab + 1)}block' \
|
||||||
|
@ -125,6 +125,7 @@ class BlockChain(
|
|||||||
previous: ChainCollectionInterface[
|
previous: ChainCollectionInterface[
|
||||||
Block[HeaderType, StateType], HeaderType, ActualStateType
|
Block[HeaderType, StateType], HeaderType, ActualStateType
|
||||||
] = await self.previous()
|
] = await self.previous()
|
||||||
|
assert isinstance(previous, ChainCollectionInterface)
|
||||||
assert_trues(
|
assert_trues(
|
||||||
await gather(
|
await gather(
|
||||||
self.verify_link(previous.reference),
|
self.verify_link(previous.reference),
|
||||||
|
@ -54,6 +54,9 @@ class ActiveStageStateProtocol(
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
) -> bool:
|
) -> bool:
|
||||||
|
assert isinstance(previous, NullableReference)
|
||||||
|
assert isinstance(header, HashPoint)
|
||||||
|
assert isinstance(state, HashPoint)
|
||||||
return await self.stage_state_protocol().verify(
|
return await self.stage_state_protocol().verify(
|
||||||
previous,
|
previous,
|
||||||
header,
|
header,
|
||||||
|
@ -106,6 +106,8 @@ class StageStage(
|
|||||||
self.previous.str(tab),
|
self.previous.str(tab),
|
||||||
hash_point_format(self.stage, tab)
|
hash_point_format(self.stage, tab)
|
||||||
)
|
)
|
||||||
|
assert isinstance(previous_str, str)
|
||||||
|
assert isinstance(stage_str, str)
|
||||||
return f'{previous_str}' \
|
return f'{previous_str}' \
|
||||||
f'{tabulate(tab)}{stage_str}'
|
f'{tabulate(tab)}{stage_str}'
|
||||||
|
|
||||||
@ -195,6 +197,8 @@ class StateStage(
|
|||||||
hash_point_format(self.previous, tab),
|
hash_point_format(self.previous, tab),
|
||||||
hash_point_format(self.state, tab),
|
hash_point_format(self.state, tab),
|
||||||
)
|
)
|
||||||
|
assert isinstance(previous_str, str)
|
||||||
|
assert isinstance(state_str, str)
|
||||||
return f'{previous_str}' \
|
return f'{previous_str}' \
|
||||||
f'{tabulate(tab)}{state_str}'
|
f'{tabulate(tab)}{state_str}'
|
||||||
|
|
||||||
|
@ -31,6 +31,8 @@ class KeyMetadata(Keyed[ActiveKeyType], Generic[ActiveKeyType, MetaDataType]):
|
|||||||
hash_point_format(self.key, tab),
|
hash_point_format(self.key, tab),
|
||||||
hash_point_format(self.metadata, tab)
|
hash_point_format(self.metadata, tab)
|
||||||
)
|
)
|
||||||
|
assert isinstance(key_str, str)
|
||||||
|
assert isinstance(metadata_str, str)
|
||||||
return f'{key_str}' \
|
return f'{key_str}' \
|
||||||
f'{tabulate(tab)}{metadata_str}'
|
f'{tabulate(tab)}{metadata_str}'
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@ class Stack(RecursiveMentionable, Generic[ElementType]):
|
|||||||
self.previous.str(tab),
|
self.previous.str(tab),
|
||||||
hash_point_format(self.element, tab),
|
hash_point_format(self.element, tab),
|
||||||
)
|
)
|
||||||
|
assert isinstance(previous_str, str)
|
||||||
|
assert isinstance(element_str, str)
|
||||||
return f'{previous_str}' \
|
return f'{previous_str}' \
|
||||||
f'{tabulate(tab)}{element_str}'
|
f'{tabulate(tab)}{element_str}'
|
||||||
|
|
||||||
@ -76,6 +78,7 @@ class Stack(RecursiveMentionable, Generic[ElementType]):
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
stack: Stack[ElementType] = await reference.resolve()
|
stack: Stack[ElementType] = await reference.resolve()
|
||||||
|
assert isinstance(stack, Stack)
|
||||||
yield stack.element
|
yield stack.element
|
||||||
async for element in cls.iter(stack.previous):
|
async for element in cls.iter(stack.previous):
|
||||||
yield element
|
yield element
|
||||||
@ -85,6 +88,7 @@ class Stack(RecursiveMentionable, Generic[ElementType]):
|
|||||||
cls,
|
cls,
|
||||||
reference: NullableReference['Stack[ElementType]']
|
reference: NullableReference['Stack[ElementType]']
|
||||||
) -> list[ElementType]:
|
) -> list[ElementType]:
|
||||||
|
assert isinstance(reference, NullableReference)
|
||||||
return list(
|
return list(
|
||||||
await gather(
|
await gather(
|
||||||
*[element.resolve() async for element in cls.iter(reference)]
|
*[element.resolve() async for element in cls.iter(reference)]
|
||||||
|
@ -33,6 +33,8 @@ class Pair(
|
|||||||
hash_point_format(self.element0, tab),
|
hash_point_format(self.element0, tab),
|
||||||
hash_point_format(self.element1, tab),
|
hash_point_format(self.element1, tab),
|
||||||
)
|
)
|
||||||
|
assert isinstance(e0_str, str)
|
||||||
|
assert isinstance(e1_str, str)
|
||||||
return f'(pair)' \
|
return f'(pair)' \
|
||||||
f'{tabulate(tab)}{e0_str}' \
|
f'{tabulate(tab)}{e0_str}' \
|
||||||
f'{tabulate(tab)}{e1_str}'
|
f'{tabulate(tab)}{e1_str}'
|
||||||
|
@ -15,9 +15,11 @@ class BinaryAction(Generic[ActiveKeyType, MetaDataType, TreeType, ActionType]):
|
|||||||
self,
|
self,
|
||||||
protocolized: BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType],
|
protocolized: BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType],
|
||||||
) -> ActionType:
|
) -> ActionType:
|
||||||
|
assert isinstance(protocolized, BinaryProtocolized)
|
||||||
if (split := await ProtocolizedBinarySplit.split_of(protocolized)) is None:
|
if (split := await ProtocolizedBinarySplit.split_of(protocolized)) is None:
|
||||||
return await self.on_null(protocolized)
|
return await self.on_null(protocolized)
|
||||||
else:
|
else:
|
||||||
|
assert isinstance(split, ProtocolizedBinarySplit)
|
||||||
return await self.on_split(split)
|
return await self.on_split(split)
|
||||||
|
|
||||||
async def on_null(
|
async def on_null(
|
||||||
|
@ -26,6 +26,8 @@ class AddAction(
|
|||||||
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType],
|
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType],
|
||||||
equal: Equal
|
equal: Equal
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
|
assert isinstance(equal, Equal)
|
||||||
if isinstance(equal, Replace):
|
if isinstance(equal, Replace):
|
||||||
return await case.protocol.tree(case.split.treel, case.split.treer, self.key)
|
return await case.protocol.tree(case.split.treel, case.split.treer, self.key)
|
||||||
else:
|
else:
|
||||||
@ -35,6 +37,7 @@ class AddAction(
|
|||||||
self,
|
self,
|
||||||
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
return await case.protocol.tree(
|
return await case.protocol.tree(
|
||||||
await self.on(case.protocolizedl()),
|
await self.on(case.protocolizedl()),
|
||||||
case.split.treer,
|
case.split.treer,
|
||||||
@ -45,6 +48,7 @@ class AddAction(
|
|||||||
self,
|
self,
|
||||||
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
return await case.protocol.tree(
|
return await case.protocol.tree(
|
||||||
case.split.treel,
|
case.split.treel,
|
||||||
await self.on(case.protocolizedr()),
|
await self.on(case.protocolizedr()),
|
||||||
@ -75,18 +79,18 @@ class MergeAction(
|
|||||||
self,
|
self,
|
||||||
protocolized: BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType],
|
protocolized: BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType],
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(protocolized, BinaryProtocolized)
|
||||||
return self.treer
|
return self.treer
|
||||||
|
|
||||||
async def on_split(
|
async def on_split(
|
||||||
self,
|
self,
|
||||||
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
protocol = case.protocol
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
split = case.split
|
return await case.protocol.tree(
|
||||||
return await protocol.tree(
|
case.split.treel,
|
||||||
split.treel,
|
|
||||||
await MergeAction(self.treer).on(case.protocolizedr()),
|
await MergeAction(self.treer).on(case.protocolizedr()),
|
||||||
split.key
|
case.split.key
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -104,12 +108,15 @@ class RemoveAction(
|
|||||||
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType],
|
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType],
|
||||||
equal: Equal
|
equal: Equal
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
|
assert isinstance(equal, Equal)
|
||||||
return await MergeAction(case.split.treer).on(case.protocolizedl())
|
return await MergeAction(case.split.treer).on(case.protocolizedl())
|
||||||
|
|
||||||
async def on_left(
|
async def on_left(
|
||||||
self,
|
self,
|
||||||
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
return await case.protocol.tree(
|
return await case.protocol.tree(
|
||||||
await self.on(case.protocolizedl()),
|
await self.on(case.protocolizedl()),
|
||||||
case.split.treer,
|
case.split.treer,
|
||||||
@ -120,6 +127,7 @@ class RemoveAction(
|
|||||||
self,
|
self,
|
||||||
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
return await case.protocol.tree(
|
return await case.protocol.tree(
|
||||||
case.split.treel,
|
case.split.treel,
|
||||||
await self.on(case.protocolizedr()),
|
await self.on(case.protocolizedr()),
|
||||||
@ -130,6 +138,7 @@ class RemoveAction(
|
|||||||
self,
|
self,
|
||||||
protocolized: BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType],
|
protocolized: BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType],
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(protocolized, BinaryProtocolized)
|
||||||
return protocolized.tree
|
return protocolized.tree
|
||||||
|
|
||||||
|
|
||||||
@ -147,22 +156,27 @@ class ContainsAction(
|
|||||||
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType],
|
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType],
|
||||||
equal: Equal
|
equal: Equal
|
||||||
) -> bool:
|
) -> bool:
|
||||||
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
|
assert isinstance(equal, Equal)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def on_left(
|
async def on_left(
|
||||||
self,
|
self,
|
||||||
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> bool:
|
) -> bool:
|
||||||
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
return await self.on(case.protocolizedl())
|
return await self.on(case.protocolizedl())
|
||||||
|
|
||||||
async def on_right(
|
async def on_right(
|
||||||
self,
|
self,
|
||||||
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
case: ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> bool:
|
) -> bool:
|
||||||
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
return await self.on(case.protocolizedr())
|
return await self.on(case.protocolizedr())
|
||||||
|
|
||||||
async def on_null(
|
async def on_null(
|
||||||
self,
|
self,
|
||||||
protocolized: BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType],
|
protocolized: BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType],
|
||||||
) -> bool:
|
) -> bool:
|
||||||
|
assert isinstance(protocolized, BinaryProtocolized)
|
||||||
return False
|
return False
|
||||||
|
@ -17,6 +17,7 @@ class Symmetric(
|
|||||||
self,
|
self,
|
||||||
protocol: BinaryCreation[ActiveKeyType, MetaDataType, TreeType],
|
protocol: BinaryCreation[ActiveKeyType, MetaDataType, TreeType],
|
||||||
):
|
):
|
||||||
|
assert isinstance(protocol, BinaryCreation)
|
||||||
self.protocol = protocol
|
self.protocol = protocol
|
||||||
|
|
||||||
def inner(
|
def inner(
|
||||||
@ -43,12 +44,14 @@ class Symmetric(
|
|||||||
self,
|
self,
|
||||||
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType]:
|
) -> BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType]:
|
||||||
|
assert isinstance(split, BinarySplit)
|
||||||
return BinaryProtocolized(self.protocol, self.inner(split))
|
return BinaryProtocolized(self.protocol, self.inner(split))
|
||||||
|
|
||||||
def protocolizedo(
|
def protocolizedo(
|
||||||
self,
|
self,
|
||||||
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType]:
|
) -> BinaryProtocolized[ActiveKeyType, MetaDataType, TreeType]:
|
||||||
|
assert isinstance(split, BinarySplit)
|
||||||
return BinaryProtocolized(self.protocol, self.outer(split))
|
return BinaryProtocolized(self.protocol, self.outer(split))
|
||||||
|
|
||||||
|
|
||||||
@ -57,12 +60,14 @@ class InnerOuter(Symmetric):
|
|||||||
self,
|
self,
|
||||||
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(split, BinarySplit)
|
||||||
return split.treel
|
return split.treel
|
||||||
|
|
||||||
def outer(
|
def outer(
|
||||||
self,
|
self,
|
||||||
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(split, BinarySplit)
|
||||||
return split.treer
|
return split.treer
|
||||||
|
|
||||||
async def tree(
|
async def tree(
|
||||||
@ -71,6 +76,7 @@ class InnerOuter(Symmetric):
|
|||||||
outer: TreeType,
|
outer: TreeType,
|
||||||
key: HashPoint[ActiveKeyType]
|
key: HashPoint[ActiveKeyType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(key, HashPoint)
|
||||||
return await self.protocol.tree(inner, outer, key)
|
return await self.protocol.tree(inner, outer, key)
|
||||||
|
|
||||||
|
|
||||||
@ -79,12 +85,14 @@ class OuterInner(Symmetric):
|
|||||||
self,
|
self,
|
||||||
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(split, BinarySplit)
|
||||||
return split.treer
|
return split.treer
|
||||||
|
|
||||||
def outer(
|
def outer(
|
||||||
self,
|
self,
|
||||||
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
split: BinarySplit[ActiveKeyType, MetaDataType, TreeType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(split, BinarySplit)
|
||||||
return split.treel
|
return split.treel
|
||||||
|
|
||||||
async def tree(
|
async def tree(
|
||||||
@ -93,4 +101,5 @@ class OuterInner(Symmetric):
|
|||||||
outer: TreeType,
|
outer: TreeType,
|
||||||
key: HashPoint[ActiveKeyType]
|
key: HashPoint[ActiveKeyType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(key, HashPoint)
|
||||||
return await self.protocol.tree(outer, inner, key)
|
return await self.protocol.tree(outer, inner, key)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import Generic, TypeVar
|
from typing import Generic, Optional, TypeVar
|
||||||
|
|
||||||
from rainbowadn.atomic import *
|
from rainbowadn.atomic import *
|
||||||
from rainbowadn.core import *
|
from rainbowadn.core import *
|
||||||
@ -22,11 +22,14 @@ class AVL(BinaryBalancing[ActiveKeyType, Integer, TreeType]):
|
|||||||
key: HashPoint[ActiveKeyType],
|
key: HashPoint[ActiveKeyType],
|
||||||
creation: BinaryCreation[ActiveKeyType, Integer, TreeType]
|
creation: BinaryCreation[ActiveKeyType, Integer, TreeType]
|
||||||
) -> HashPoint[Integer]:
|
) -> HashPoint[Integer]:
|
||||||
|
assert isinstance(key, HashPoint)
|
||||||
assert isinstance(creation, BinaryCreation)
|
assert isinstance(creation, BinaryCreation)
|
||||||
height_l, height_r = await gather(
|
height_l, height_r = await gather(
|
||||||
self.height(BinaryProtocolized(creation, treel)),
|
self.height(BinaryProtocolized(creation, treel)),
|
||||||
self.height(BinaryProtocolized(creation, treer)),
|
self.height(BinaryProtocolized(creation, treer)),
|
||||||
)
|
)
|
||||||
|
assert isinstance(height_l, int)
|
||||||
|
assert isinstance(height_r, int)
|
||||||
return HashPoint.of(
|
return HashPoint.of(
|
||||||
Integer(
|
Integer(
|
||||||
1
|
1
|
||||||
@ -43,12 +46,22 @@ class AVL(BinaryBalancing[ActiveKeyType, Integer, TreeType]):
|
|||||||
cls,
|
cls,
|
||||||
protocolized: BinaryProtocolized[ActiveKeyType, Integer, TreeType],
|
protocolized: BinaryProtocolized[ActiveKeyType, Integer, TreeType],
|
||||||
) -> int:
|
) -> int:
|
||||||
|
assert isinstance(protocolized, BinaryProtocolized)
|
||||||
return await HeightAction().on(protocolized)
|
return await HeightAction().on(protocolized)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def full_height(
|
||||||
|
cls,
|
||||||
|
protocolized: BinaryProtocolized[ActiveKeyType, Integer, TreeType],
|
||||||
|
) -> tuple[int, Optional[BinarySplit[ActiveKeyType, Integer, TreeType]]]:
|
||||||
|
assert isinstance(protocolized, BinaryProtocolized)
|
||||||
|
return await FullHeightAction().on(protocolized)
|
||||||
|
|
||||||
async def balance(
|
async def balance(
|
||||||
self,
|
self,
|
||||||
protocolized: BinaryProtocolized[ActiveKeyType, Integer, TreeType],
|
protocolized: BinaryProtocolized[ActiveKeyType, Integer, TreeType],
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(protocolized, BinaryProtocolized)
|
||||||
return await BalanceAction().on(protocolized)
|
return await BalanceAction().on(protocolized)
|
||||||
|
|
||||||
|
|
||||||
@ -60,16 +73,45 @@ class HeightAction(
|
|||||||
self,
|
self,
|
||||||
protocolized: BinaryProtocolized[ActiveKeyType, Integer, TreeType],
|
protocolized: BinaryProtocolized[ActiveKeyType, Integer, TreeType],
|
||||||
) -> int:
|
) -> int:
|
||||||
|
assert isinstance(protocolized, BinaryProtocolized)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
async def on_split(
|
async def on_split(
|
||||||
self,
|
self,
|
||||||
case: ProtocolizedBinarySplit[ActiveKeyType, Integer, TreeType]
|
case: ProtocolizedBinarySplit[ActiveKeyType, Integer, TreeType]
|
||||||
) -> int:
|
) -> int:
|
||||||
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
metadata: Integer = await case.split.metadata.resolve()
|
metadata: Integer = await case.split.metadata.resolve()
|
||||||
|
assert isinstance(metadata, Integer)
|
||||||
return metadata.integer
|
return metadata.integer
|
||||||
|
|
||||||
|
|
||||||
|
class FullHeightAction(
|
||||||
|
BinaryAction[
|
||||||
|
ActiveKeyType,
|
||||||
|
Integer,
|
||||||
|
TreeType,
|
||||||
|
tuple[int, Optional[BinarySplit[ActiveKeyType, Integer, TreeType]]]
|
||||||
|
],
|
||||||
|
Generic[ActiveKeyType, TreeType]
|
||||||
|
):
|
||||||
|
async def on_null(
|
||||||
|
self,
|
||||||
|
protocolized: BinaryProtocolized[ActiveKeyType, Integer, TreeType],
|
||||||
|
) -> tuple[int, Optional[BinarySplit[ActiveKeyType, Integer, TreeType]]]:
|
||||||
|
assert isinstance(protocolized, BinaryProtocolized)
|
||||||
|
return 0, None
|
||||||
|
|
||||||
|
async def on_split(
|
||||||
|
self,
|
||||||
|
case: ProtocolizedBinarySplit[ActiveKeyType, Integer, TreeType]
|
||||||
|
) -> tuple[int, Optional[BinarySplit[ActiveKeyType, Integer, TreeType]]]:
|
||||||
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
|
metadata: Integer = await case.split.metadata.resolve()
|
||||||
|
assert isinstance(metadata, Integer)
|
||||||
|
return metadata.integer, case.split
|
||||||
|
|
||||||
|
|
||||||
class BalanceAction(
|
class BalanceAction(
|
||||||
BinaryAction[ActiveKeyType, Integer, TreeType, TreeType],
|
BinaryAction[ActiveKeyType, Integer, TreeType, TreeType],
|
||||||
Generic[ActiveKeyType, TreeType]
|
Generic[ActiveKeyType, TreeType]
|
||||||
@ -78,22 +120,30 @@ class BalanceAction(
|
|||||||
self,
|
self,
|
||||||
protocolized: BinaryProtocolized[ActiveKeyType, Integer, TreeType],
|
protocolized: BinaryProtocolized[ActiveKeyType, Integer, TreeType],
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
|
assert isinstance(protocolized, BinaryProtocolized)
|
||||||
return protocolized.tree
|
return protocolized.tree
|
||||||
|
|
||||||
async def on_split(
|
async def on_split(
|
||||||
self,
|
self,
|
||||||
case: ProtocolizedBinarySplit[ActiveKeyType, Integer, TreeType]
|
case: ProtocolizedBinarySplit[ActiveKeyType, Integer, TreeType]
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
height_l, height_r = await gather(
|
assert isinstance(case, ProtocolizedBinarySplit)
|
||||||
AVL.height(case.protocolizedl()),
|
(height_l, splitl), (height_r, splitr) = await gather(
|
||||||
AVL.height(case.protocolizedr()),
|
AVL.full_height(case.protocolizedl()),
|
||||||
|
AVL.full_height(case.protocolizedr()),
|
||||||
)
|
)
|
||||||
|
assert isinstance(height_l, int)
|
||||||
|
assert isinstance(height_r, int)
|
||||||
delta = height_l - height_r
|
delta = height_l - height_r
|
||||||
assert isinstance(delta, int)
|
assert isinstance(delta, int)
|
||||||
if delta < -1:
|
if delta < -1:
|
||||||
return await self.on_symmetric(InnerOuter(case.protocol), case.split)
|
splitr: BinarySplit[ActiveKeyType, Integer, TreeType]
|
||||||
|
assert isinstance(splitr, BinarySplit)
|
||||||
|
return await self.on_symmetric(InnerOuter(case.protocol), case.split.treel, case.split.key, splitr)
|
||||||
elif delta > 1:
|
elif delta > 1:
|
||||||
return await self.on_symmetric(OuterInner(case.protocol), case.split)
|
splitl: BinarySplit[ActiveKeyType, Integer, TreeType]
|
||||||
|
assert isinstance(splitl, BinarySplit)
|
||||||
|
return await self.on_symmetric(OuterInner(case.protocol), case.split.treer, case.split.key, splitl)
|
||||||
else:
|
else:
|
||||||
return case.tree
|
return case.tree
|
||||||
|
|
||||||
@ -101,19 +151,24 @@ class BalanceAction(
|
|||||||
async def on_symmetric(
|
async def on_symmetric(
|
||||||
cls,
|
cls,
|
||||||
symmetry: Symmetric[ActiveKeyType, Integer, TreeType],
|
symmetry: Symmetric[ActiveKeyType, Integer, TreeType],
|
||||||
split: BinarySplit[ActiveKeyType, Integer, TreeType]
|
treei: TreeType,
|
||||||
|
key: HashPoint[ActiveKeyType],
|
||||||
|
splito: BinarySplit[ActiveKeyType, Integer, TreeType],
|
||||||
) -> TreeType:
|
) -> TreeType:
|
||||||
assert isinstance(symmetry, Symmetric)
|
assert isinstance(symmetry, Symmetric)
|
||||||
assert isinstance(split, BinarySplit)
|
assert isinstance(key, HashPoint)
|
||||||
splito = await symmetry.protocol.fsplit(symmetry.outer(split))
|
assert isinstance(splito, BinarySplit)
|
||||||
height_oi, height_oo = await gather(
|
(height_oi, splitoi), height_oo = await gather(
|
||||||
AVL.height(symmetry.protocolizedi(splito)),
|
AVL.full_height(symmetry.protocolizedi(splito)),
|
||||||
AVL.height(symmetry.protocolizedo(splito)),
|
AVL.height(symmetry.protocolizedo(splito)),
|
||||||
)
|
)
|
||||||
|
assert isinstance(height_oi, int)
|
||||||
|
assert isinstance(height_oo, int)
|
||||||
if height_oi > height_oo:
|
if height_oi > height_oo:
|
||||||
splitoi = await symmetry.protocol.fsplit(symmetry.inner(splito))
|
splitoi: BinarySplit[ActiveKeyType, Integer, TreeType]
|
||||||
|
assert isinstance(splitoi, BinarySplit)
|
||||||
inner, outer = await gather(
|
inner, outer = await gather(
|
||||||
symmetry.tree(symmetry.inner(split), symmetry.inner(splitoi), split.key),
|
symmetry.tree(treei, symmetry.inner(splitoi), key),
|
||||||
symmetry.tree(symmetry.outer(splitoi), symmetry.outer(splito), splito.key),
|
symmetry.tree(symmetry.outer(splitoi), symmetry.outer(splito), splito.key),
|
||||||
)
|
)
|
||||||
return await symmetry.tree(
|
return await symmetry.tree(
|
||||||
@ -123,7 +178,7 @@ class BalanceAction(
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return await symmetry.tree(
|
return await symmetry.tree(
|
||||||
await symmetry.tree(symmetry.inner(split), symmetry.inner(splito), split.key),
|
await symmetry.tree(treei, symmetry.inner(splito), key),
|
||||||
symmetry.outer(splito),
|
symmetry.outer(splito),
|
||||||
splito.key
|
splito.key
|
||||||
)
|
)
|
||||||
|
@ -42,6 +42,9 @@ class BinaryTree(RecursiveMentionable, Generic[TreeKeyType]):
|
|||||||
hash_point_format(self.key, tab),
|
hash_point_format(self.key, tab),
|
||||||
self.treer.str(tab),
|
self.treer.str(tab),
|
||||||
)
|
)
|
||||||
|
assert isinstance(treel_str, str)
|
||||||
|
assert isinstance(key_str, str)
|
||||||
|
assert isinstance(treer_str, str)
|
||||||
return f'{treel_str}' \
|
return f'{treel_str}' \
|
||||||
f'{tabulate(tab)}{key_str}' \
|
f'{tabulate(tab)}{key_str}' \
|
||||||
f'{tabulate(tab)}{treer_str}'
|
f'{tabulate(tab)}{treer_str}'
|
||||||
|
@ -22,12 +22,5 @@ class BinaryCreation(Generic[ActiveKeyType, MetaDataType, TreeType]):
|
|||||||
"""result of this method is supposed to be used right after the call, therefore all values are resolved"""
|
"""result of this method is supposed to be used right after the call, therefore all values are resolved"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
async def fsplit(self, tree: TreeType) -> BinarySplit[
|
|
||||||
ActiveKeyType, MetaDataType, TreeType
|
|
||||||
]:
|
|
||||||
split: Optional[BinarySplit[ActiveKeyType, MetaDataType, TreeType]] = await self.split(tree)
|
|
||||||
assert split is not None
|
|
||||||
return split
|
|
||||||
|
|
||||||
async def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
|
async def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -42,6 +42,7 @@ class ProtocolizedBinarySplit(
|
|||||||
) -> Optional[
|
) -> Optional[
|
||||||
'ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]'
|
'ProtocolizedBinarySplit[ActiveKeyType, MetaDataType, TreeType]'
|
||||||
]:
|
]:
|
||||||
|
assert isinstance(protocolized, BinaryProtocolized)
|
||||||
if (split := await protocolized.split()) is None:
|
if (split := await protocolized.split()) is None:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
@ -3,6 +3,7 @@ from typing import TypeVar
|
|||||||
|
|
||||||
from .hashpoint import HashPoint
|
from .hashpoint import HashPoint
|
||||||
from .hashresolver import HashResolver
|
from .hashresolver import HashResolver
|
||||||
|
from .mentionable import Mentionable
|
||||||
from .resolvermetaorigin import ResolverMetaOrigin
|
from .resolvermetaorigin import ResolverMetaOrigin
|
||||||
|
|
||||||
__all__ = ('ExtendableResolver',)
|
__all__ = ('ExtendableResolver',)
|
||||||
@ -19,4 +20,5 @@ class ExtendableResolver(HashResolver, abc.ABC):
|
|||||||
return ResolverMetaOrigin(await self.extend(hash_point)).hash_point(hash_point.factory, hash_point.point)
|
return ResolverMetaOrigin(await self.extend(hash_point)).hash_point(hash_point.factory, hash_point.point)
|
||||||
|
|
||||||
async def migrate_resolved(self, mentioned: Mentioned) -> Mentioned:
|
async def migrate_resolved(self, mentioned: Mentioned) -> Mentioned:
|
||||||
|
assert isinstance(mentioned, Mentionable)
|
||||||
return await (await self.migrate(HashPoint.of(mentioned))).resolve()
|
return await (await self.migrate(HashPoint.of(mentioned))).resolve()
|
||||||
|
@ -9,6 +9,7 @@ async def hash_point_format(hash_point: HashPoint, tab: int) -> str:
|
|||||||
assert isinstance(hash_point, HashPoint)
|
assert isinstance(hash_point, HashPoint)
|
||||||
assert isinstance(tab, int)
|
assert isinstance(tab, int)
|
||||||
value: Mentionable = await hash_point.resolve()
|
value: Mentionable = await hash_point.resolve()
|
||||||
|
assert isinstance(value, Mentionable)
|
||||||
if isinstance(value, RecursiveMentionable):
|
if isinstance(value, RecursiveMentionable):
|
||||||
return await value.str(tab)
|
return await value.str(tab)
|
||||||
else:
|
else:
|
||||||
|
@ -9,6 +9,7 @@ Mentioned = TypeVar('Mentioned')
|
|||||||
|
|
||||||
class Origin(Generic[Mentioned]):
|
class Origin(Generic[Mentioned]):
|
||||||
def __init__(self, factory: RainbowFactory[Mentioned]):
|
def __init__(self, factory: RainbowFactory[Mentioned]):
|
||||||
|
assert isinstance(factory, RainbowFactory)
|
||||||
self.factory = factory
|
self.factory = factory
|
||||||
|
|
||||||
async def resolve(self) -> Mentioned:
|
async def resolve(self) -> Mentioned:
|
||||||
|
@ -25,6 +25,7 @@ class StaticMentionable(Mentionable, abc.ABC):
|
|||||||
|
|
||||||
class StaticFactory(RainbowFactory[StaticMentioned], Generic[StaticMentioned]):
|
class StaticFactory(RainbowFactory[StaticMentioned], Generic[StaticMentioned]):
|
||||||
def __init__(self, cls: Type[StaticMentioned]):
|
def __init__(self, cls: Type[StaticMentioned]):
|
||||||
|
assert issubclass(cls, StaticMentionable)
|
||||||
self.cls: Type[StaticMentioned] = cls
|
self.cls: Type[StaticMentioned] = cls
|
||||||
|
|
||||||
def from_bytes(self, source: bytes, resolver: HashResolver) -> StaticMentioned:
|
def from_bytes(self, source: bytes, resolver: HashResolver) -> StaticMentioned:
|
||||||
|
@ -26,6 +26,7 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]):
|
|||||||
assert isinstance(decrypted, Mentionable)
|
assert isinstance(decrypted, Mentionable)
|
||||||
|
|
||||||
self.factory: RainbowFactory[EncryptedType] = decrypted.__factory__()
|
self.factory: RainbowFactory[EncryptedType] = decrypted.__factory__()
|
||||||
|
assert isinstance(self.factory, RainbowFactory)
|
||||||
self.key = key
|
self.key = key
|
||||||
|
|
||||||
self.resolution = resolution
|
self.resolution = resolution
|
||||||
@ -38,6 +39,7 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def encrypt(cls, decrypted: EncryptedType, key: bytes) -> 'Encrypted[EncryptedType]':
|
async def encrypt(cls, decrypted: EncryptedType, key: bytes) -> 'Encrypted[EncryptedType]':
|
||||||
|
assert isinstance(decrypted, Mentionable)
|
||||||
assert isinstance(key, bytes)
|
assert isinstance(key, bytes)
|
||||||
hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else ()
|
hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else ()
|
||||||
resolution = tuple(
|
resolution = tuple(
|
||||||
@ -79,6 +81,10 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]):
|
|||||||
hashpoints: tuple[HashPoint, ...],
|
hashpoints: tuple[HashPoint, ...],
|
||||||
decrypted: EncryptedType
|
decrypted: EncryptedType
|
||||||
) -> 'Encrypted[EncryptedType]':
|
) -> 'Encrypted[EncryptedType]':
|
||||||
|
assert isinstance(key, bytes)
|
||||||
|
assert isinstance(resolution, tuple)
|
||||||
|
assert isinstance(hashpoints, tuple)
|
||||||
|
assert isinstance(decrypted, Mentionable)
|
||||||
mapping: dict[bytes, HashPoint[Encrypted]] = {
|
mapping: dict[bytes, HashPoint[Encrypted]] = {
|
||||||
hash_point.point: encrypted for hash_point, encrypted in zip(hashpoints, resolution)
|
hash_point.point: encrypted for hash_point, encrypted in zip(hashpoints, resolution)
|
||||||
}
|
}
|
||||||
@ -122,6 +128,7 @@ class EncryptedFactory(RainbowFactory[Encrypted[EncryptedType]], Generic[Encrypt
|
|||||||
plain[8 + resolution_size * HashPoint.HASH_LENGTH:],
|
plain[8 + resolution_size * HashPoint.HASH_LENGTH:],
|
||||||
resolver,
|
resolver,
|
||||||
)
|
)
|
||||||
|
assert isinstance(decrypted, Mentionable)
|
||||||
hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else ()
|
hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else ()
|
||||||
assert_eq(len(hashpoints), resolution_size)
|
assert_eq(len(hashpoints), resolution_size)
|
||||||
resolution: tuple[HashPoint[Encrypted], ...] = tuple(
|
resolution: tuple[HashPoint[Encrypted], ...] = tuple(
|
||||||
@ -152,6 +159,7 @@ class EncryptedResolver(HashResolver):
|
|||||||
async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
|
async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
|
||||||
assert isinstance(point, bytes)
|
assert isinstance(point, bytes)
|
||||||
encrypted: Encrypted = await self.mapping[point].resolve()
|
encrypted: Encrypted = await self.mapping[point].resolve()
|
||||||
|
assert isinstance(encrypted, Encrypted)
|
||||||
return HashPoint.bytes_of_mentioned(encrypted.decrypted), EncryptedResolver(encrypted.mapping, self.key)
|
return HashPoint.bytes_of_mentioned(encrypted.decrypted), EncryptedResolver(encrypted.mapping, self.key)
|
||||||
|
|
||||||
|
|
||||||
@ -167,7 +175,9 @@ class ShortcutOrigin(Origin[Encrypted[EncryptedType]], Generic[EncryptedType]):
|
|||||||
|
|
||||||
async def resolve(self) -> Encrypted[EncryptedType]:
|
async def resolve(self) -> Encrypted[EncryptedType]:
|
||||||
source: Encrypted = await self.hashpoint.resolve()
|
source: Encrypted = await self.hashpoint.resolve()
|
||||||
|
assert isinstance(source, Encrypted)
|
||||||
encrypted: Encrypted[EncryptedType] = self.factory.from_bytes(bytes(source), ShortcutResolver(source))
|
encrypted: Encrypted[EncryptedType] = self.factory.from_bytes(bytes(source), ShortcutResolver(source))
|
||||||
|
assert isinstance(encrypted, Encrypted)
|
||||||
assert_eq(HashPoint.of(encrypted), self.hashpoint)
|
assert_eq(HashPoint.of(encrypted), self.hashpoint)
|
||||||
return encrypted
|
return encrypted
|
||||||
|
|
||||||
@ -188,6 +198,7 @@ class ShortcutResolver(HashResolver):
|
|||||||
async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
|
async def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
|
||||||
assert isinstance(point, bytes)
|
assert isinstance(point, bytes)
|
||||||
resolved: Encrypted = await self.mapping[point].resolve()
|
resolved: Encrypted = await self.mapping[point].resolve()
|
||||||
|
assert isinstance(resolved, Encrypted)
|
||||||
return (
|
return (
|
||||||
HashPoint.bytes_of_mentioned(resolved),
|
HashPoint.bytes_of_mentioned(resolved),
|
||||||
ShortcutResolver(resolved)
|
ShortcutResolver(resolved)
|
||||||
|
@ -41,9 +41,11 @@ class NullableReference(RecursiveMentionable, Generic[Referenced]):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def off(cls, value: Referenced) -> 'NullableReference[Referenced]':
|
def off(cls, value: Referenced) -> 'NullableReference[Referenced]':
|
||||||
|
assert isinstance(value, Mentionable)
|
||||||
return cls.of(HashPoint.of(value))
|
return cls.of(HashPoint.of(value))
|
||||||
|
|
||||||
async def str(self, tab: int) -> str:
|
async def str(self, tab: int) -> str:
|
||||||
|
assert isinstance(tab, int)
|
||||||
if self.null():
|
if self.null():
|
||||||
return f'-'
|
return f'-'
|
||||||
else:
|
else:
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
import functools
|
import functools
|
||||||
import time
|
import time
|
||||||
from typing import Generic, TypeVar
|
from contextlib import ExitStack
|
||||||
|
from typing import Callable, Generic, TypeVar
|
||||||
__all__ = ('Instrumentation', 'Counter', 'Concurrency',)
|
|
||||||
|
|
||||||
|
__all__ = ('Instrumentation', 'Counter', 'Concurrency', 'EntryExit',)
|
||||||
|
|
||||||
IType = TypeVar('IType')
|
IType = TypeVar('IType')
|
||||||
|
|
||||||
|
|
||||||
class Instrumentation(Generic[IType]):
|
class Instrumentation(Generic[IType]):
|
||||||
deinstrumentation = {}
|
deinstrumentation = {}
|
||||||
|
method: Callable
|
||||||
|
wrap: Callable
|
||||||
|
|
||||||
def __init__(self, target, methodname: str):
|
def __init__(self, target, methodname: str):
|
||||||
|
assert isinstance(methodname, str)
|
||||||
|
assert callable(getattr(target, methodname))
|
||||||
self.target = target
|
self.target = target
|
||||||
self.methodname = methodname
|
self.methodname = methodname
|
||||||
|
|
||||||
@ -21,6 +25,7 @@ class Instrumentation(Generic[IType]):
|
|||||||
def __enter__(self: IType) -> IType:
|
def __enter__(self: IType) -> IType:
|
||||||
assert not hasattr(self, 'method')
|
assert not hasattr(self, 'method')
|
||||||
self.method = getattr(self.target, self.methodname)
|
self.method = getattr(self.target, self.methodname)
|
||||||
|
assert callable(self.method)
|
||||||
|
|
||||||
@functools.wraps(self.method)
|
@functools.wraps(self.method)
|
||||||
def wrap(*args, **kwargs):
|
def wrap(*args, **kwargs):
|
||||||
@ -45,9 +50,13 @@ class Instrumentation(Generic[IType]):
|
|||||||
self.schedule_deinstrumentation()
|
self.schedule_deinstrumentation()
|
||||||
self.deinstrument()
|
self.deinstrument()
|
||||||
|
|
||||||
|
def enter(self: IType, stack: ExitStack) -> IType:
|
||||||
|
return stack.enter_context(self)
|
||||||
|
|
||||||
|
|
||||||
class Counter(Instrumentation):
|
class Counter(Instrumentation):
|
||||||
def __init__(self, target, methodname: str):
|
def __init__(self, target, methodname: str):
|
||||||
|
assert isinstance(methodname, str)
|
||||||
super().__init__(target, methodname)
|
super().__init__(target, methodname)
|
||||||
self.counter = 0
|
self.counter = 0
|
||||||
|
|
||||||
@ -60,19 +69,39 @@ class Concurrency(Instrumentation):
|
|||||||
start = time.time()
|
start = time.time()
|
||||||
|
|
||||||
def __init__(self, target, methodname: str):
|
def __init__(self, target, methodname: str):
|
||||||
|
assert isinstance(methodname, str)
|
||||||
super().__init__(target, methodname)
|
super().__init__(target, methodname)
|
||||||
self.concurrency = 0
|
self.concurrency = 0
|
||||||
self.logs: list[tuple[float, int]] = []
|
self.log: list[tuple[float, int]] = []
|
||||||
|
|
||||||
def time(self) -> float:
|
def time(self) -> float:
|
||||||
return time.time() - self.start
|
return time.time() - self.start
|
||||||
|
|
||||||
|
def point(self) -> tuple[float, int]:
|
||||||
|
return self.time(), self.concurrency
|
||||||
|
|
||||||
async def instrument(self, method, *args, **kwargs):
|
async def instrument(self, method, *args, **kwargs):
|
||||||
self.logs.append((self.time(), self.concurrency))
|
self.log.append(self.point())
|
||||||
self.concurrency += 1
|
self.concurrency += 1
|
||||||
self.logs.append((self.time(), self.concurrency))
|
self.log.append(self.point())
|
||||||
result = await method(*args, **kwargs)
|
result = await method(*args, **kwargs)
|
||||||
self.logs.append((self.time(), self.concurrency))
|
self.log.append(self.point())
|
||||||
self.concurrency -= 1
|
self.concurrency -= 1
|
||||||
self.logs.append((self.time(), self.concurrency))
|
self.log.append(self.point())
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class EntryExit(Instrumentation):
|
||||||
|
def __init__(self, target, methodname: str, point: Callable[[], tuple[float, int]]):
|
||||||
|
assert callable(point)
|
||||||
|
assert isinstance(methodname, str)
|
||||||
|
super().__init__(target, methodname)
|
||||||
|
self.point = point
|
||||||
|
self.entry_log: list[tuple[float, int]] = []
|
||||||
|
self.exit_log: list[tuple[float, int]] = []
|
||||||
|
|
||||||
|
async def instrument(self, method, *args, **kwargs):
|
||||||
|
self.entry_log.append(self.point())
|
||||||
|
result = await method(*args, **kwargs)
|
||||||
|
self.exit_log.append(self.point())
|
||||||
return result
|
return result
|
||||||
|
4
rainbowadn/testing/resolvers/__init__.py
Normal file
4
rainbowadn/testing/resolvers/__init__.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
from .cachingresolver import CachingResolver
|
||||||
|
from .delayedresolver import DelayedResolver
|
||||||
|
from .dictresolver import DictResolver
|
||||||
|
from .failresolver import FailResolver
|
30
rainbowadn/testing/resolvers/cachingresolver.py
Normal file
30
rainbowadn/testing/resolvers/cachingresolver.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.core import *
|
||||||
|
|
||||||
|
__all__ = ('CachingResolver',)
|
||||||
|
|
||||||
|
Mentioned = TypeVar('Mentioned')
|
||||||
|
|
||||||
|
|
||||||
|
class CachingResolver(ExtendableResolver):
|
||||||
|
def __init__(self, resolver: HashResolver):
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
self.resolver = resolver
|
||||||
|
self.cache: dict[bytes, tuple[bytes, CachingResolver]] = {}
|
||||||
|
|
||||||
|
async def resolve(self, point: bytes) -> tuple[bytes, HashResolver]:
|
||||||
|
assert isinstance(point, bytes)
|
||||||
|
if point not in self.cache:
|
||||||
|
resolved, resolver = await self.resolver.resolve(point)
|
||||||
|
assert isinstance(resolved, bytes)
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
self.cache[point] = resolved, CachingResolver(resolver)
|
||||||
|
return self.cache[point]
|
||||||
|
|
||||||
|
async def extend(self, hash_point: HashPoint[Mentioned]) -> ExtendableResolver:
|
||||||
|
assert isinstance(hash_point, HashPoint)
|
||||||
|
if isinstance(self.resolver, ExtendableResolver):
|
||||||
|
return CachingResolver(await self.resolver.extend(hash_point))
|
||||||
|
else:
|
||||||
|
raise TypeError
|
@ -10,6 +10,8 @@ Mentioned = TypeVar('Mentioned')
|
|||||||
|
|
||||||
class DelayedResolver(ExtendableResolver):
|
class DelayedResolver(ExtendableResolver):
|
||||||
def __init__(self, resolver: HashResolver, delay: Callable[[], float]):
|
def __init__(self, resolver: HashResolver, delay: Callable[[], float]):
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
assert callable(delay)
|
||||||
self.resolver = resolver
|
self.resolver = resolver
|
||||||
self.delay = delay
|
self.delay = delay
|
||||||
|
|
||||||
@ -20,9 +22,12 @@ class DelayedResolver(ExtendableResolver):
|
|||||||
assert isinstance(point, bytes)
|
assert isinstance(point, bytes)
|
||||||
await self.sleep()
|
await self.sleep()
|
||||||
resolved, resolver = await self.resolver.resolve(point)
|
resolved, resolver = await self.resolver.resolve(point)
|
||||||
|
assert isinstance(resolved, bytes)
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
return resolved, DelayedResolver(resolver, self.delay)
|
return resolved, DelayedResolver(resolver, self.delay)
|
||||||
|
|
||||||
async def extend(self, hash_point: HashPoint[Mentioned]) -> ExtendableResolver:
|
async def extend(self, hash_point: HashPoint[Mentioned]) -> ExtendableResolver:
|
||||||
|
assert isinstance(hash_point, HashPoint)
|
||||||
if isinstance(self.resolver, ExtendableResolver):
|
if isinstance(self.resolver, ExtendableResolver):
|
||||||
return DelayedResolver(await self.resolver.extend(hash_point), self.delay)
|
return DelayedResolver(await self.resolver.extend(hash_point), self.delay)
|
||||||
else:
|
else:
|
@ -30,5 +30,6 @@ class DictResolver(ExtendableResolver):
|
|||||||
)
|
)
|
||||||
|
|
||||||
async def extend(self, hash_point: HashPoint[Mentioned]) -> 'ExtendableResolver':
|
async def extend(self, hash_point: HashPoint[Mentioned]) -> 'ExtendableResolver':
|
||||||
|
assert isinstance(hash_point, HashPoint)
|
||||||
await self.save(hash_point)
|
await self.save(hash_point)
|
||||||
return self
|
return self
|
@ -16,9 +16,8 @@ from rainbowadn.encryption import *
|
|||||||
from rainbowadn.nullability import *
|
from rainbowadn.nullability import *
|
||||||
from rainbowadn.v13 import *
|
from rainbowadn.v13 import *
|
||||||
from rainbowadn.wrisbt import *
|
from rainbowadn.wrisbt import *
|
||||||
from .delayedresolver import DelayedResolver
|
|
||||||
from .dictresolver import DictResolver
|
|
||||||
from .instrumentation import *
|
from .instrumentation import *
|
||||||
|
from .resolvers import *
|
||||||
|
|
||||||
|
|
||||||
class TestAll(unittest.IsolatedAsyncioTestCase):
|
class TestAll(unittest.IsolatedAsyncioTestCase):
|
||||||
|
@ -20,6 +20,7 @@ class ValidReference(RecursiveMentionable, Generic[Referenced]):
|
|||||||
|
|
||||||
async def resolve(self) -> Referenced:
|
async def resolve(self) -> Referenced:
|
||||||
referenced: Referenced = await self.reference.resolve()
|
referenced: Referenced = await self.reference.resolve()
|
||||||
|
assert isinstance(referenced, Mentionable)
|
||||||
assert self.reference.point < (await self.protocol.threshold(referenced))
|
assert self.reference.point < (await self.protocol.threshold(referenced))
|
||||||
return referenced
|
return referenced
|
||||||
|
|
||||||
|
@ -104,8 +104,11 @@ class BankState(RecursiveMentionable, StaticMentionable):
|
|||||||
self,
|
self,
|
||||||
transaction: Transaction
|
transaction: Transaction
|
||||||
) -> 'BankState':
|
) -> 'BankState':
|
||||||
|
assert isinstance(transaction, Transaction)
|
||||||
miner = self.miner_nullable()
|
miner = self.miner_nullable()
|
||||||
|
assert isinstance(miner, Nullable)
|
||||||
minted: ActiveBinaryTree[Coin, Integer] = self.minted_tree()
|
minted: ActiveBinaryTree[Coin, Integer] = self.minted_tree()
|
||||||
|
assert isinstance(minted, ActiveBinaryTree)
|
||||||
async for coin, miner in transaction.iter_coins(self.mint(), miner):
|
async for coin, miner in transaction.iter_coins(self.mint(), miner):
|
||||||
minted_contains, minted = await gather(
|
minted_contains, minted = await gather(
|
||||||
minted.contains(HashPoint.of(coin)),
|
minted.contains(HashPoint.of(coin)),
|
||||||
@ -119,11 +122,13 @@ class BankState(RecursiveMentionable, StaticMentionable):
|
|||||||
self,
|
self,
|
||||||
transaction: Transaction
|
transaction: Transaction
|
||||||
) -> 'BankState':
|
) -> 'BankState':
|
||||||
|
assert isinstance(transaction, Transaction)
|
||||||
verified, bank_state = await gather(
|
verified, bank_state = await gather(
|
||||||
self.verify(transaction),
|
self.verify(transaction),
|
||||||
self._mint_coins(transaction),
|
self._mint_coins(transaction),
|
||||||
)
|
)
|
||||||
assert_true(verified)
|
assert_true(verified)
|
||||||
|
assert isinstance(bank_state, BankState)
|
||||||
return bank_state
|
return bank_state
|
||||||
|
|
||||||
def miner_nullable(self) -> Nullable[HashPoint[Subject]]:
|
def miner_nullable(self) -> Nullable[HashPoint[Subject]]:
|
||||||
@ -161,6 +166,10 @@ class BankState(RecursiveMentionable, StaticMentionable):
|
|||||||
self.used.str(tab + 1),
|
self.used.str(tab + 1),
|
||||||
hash_point_format(self.length, tab + 1),
|
hash_point_format(self.length, tab + 1),
|
||||||
)
|
)
|
||||||
|
assert isinstance(miner_str, str)
|
||||||
|
assert isinstance(minted_str, str)
|
||||||
|
assert isinstance(used_str, str)
|
||||||
|
assert isinstance(length_str, str)
|
||||||
return f'(' \
|
return f'(' \
|
||||||
f'{tabulate(tab + 1)}bank' \
|
f'{tabulate(tab + 1)}bank' \
|
||||||
f'{tabulate(tab + 1)}(miner)' \
|
f'{tabulate(tab + 1)}(miner)' \
|
||||||
|
@ -53,6 +53,8 @@ class CoinData(RecursiveMentionable, StaticMentionable):
|
|||||||
hash_point_format(self.owner, tab),
|
hash_point_format(self.owner, tab),
|
||||||
hash_point_format(self.value, tab),
|
hash_point_format(self.value, tab),
|
||||||
)
|
)
|
||||||
|
assert isinstance(owner_str, str)
|
||||||
|
assert isinstance(value_str, str)
|
||||||
return f'{owner_str}' \
|
return f'{owner_str}' \
|
||||||
f'{tabulate(tab)}{value_str}'
|
f'{tabulate(tab)}{value_str}'
|
||||||
|
|
||||||
@ -98,6 +100,8 @@ class Coin(RecursiveMentionable, StaticMentionable):
|
|||||||
hash_point_format(self.data, tab + 1),
|
hash_point_format(self.data, tab + 1),
|
||||||
hash_point_format(self.index, tab + 1),
|
hash_point_format(self.index, tab + 1),
|
||||||
)
|
)
|
||||||
|
assert isinstance(data_str, str)
|
||||||
|
assert isinstance(index_str, str)
|
||||||
return f'(' \
|
return f'(' \
|
||||||
f'{tabulate(tab + 1)}coin' \
|
f'{tabulate(tab + 1)}coin' \
|
||||||
f'{tabulate(tab + 1)}{data_str}' \
|
f'{tabulate(tab + 1)}{data_str}' \
|
||||||
@ -145,6 +149,8 @@ class TransactionData(RecursiveMentionable, StaticMentionable):
|
|||||||
)
|
)
|
||||||
|
|
||||||
async def _signature_verify(self, coin: Coin, signature: Signature) -> bool:
|
async def _signature_verify(self, coin: Coin, signature: Signature) -> bool:
|
||||||
|
assert isinstance(coin, Coin)
|
||||||
|
assert isinstance(signature, Signature)
|
||||||
assert_true(
|
assert_true(
|
||||||
signature.verify(
|
signature.verify(
|
||||||
await coin.owner_resolved(),
|
await coin.owner_resolved(),
|
||||||
@ -157,6 +163,7 @@ class TransactionData(RecursiveMentionable, StaticMentionable):
|
|||||||
self,
|
self,
|
||||||
signatures: NullableReference[Stack[Signature]]
|
signatures: NullableReference[Stack[Signature]]
|
||||||
) -> bool:
|
) -> bool:
|
||||||
|
assert isinstance(signatures, NullableReference)
|
||||||
assert_trues(
|
assert_trues(
|
||||||
await gather(
|
await gather(
|
||||||
*[
|
*[
|
||||||
@ -207,6 +214,8 @@ class TransactionData(RecursiveMentionable, StaticMentionable):
|
|||||||
self._total_in(),
|
self._total_in(),
|
||||||
self._total_out(),
|
self._total_out(),
|
||||||
)
|
)
|
||||||
|
assert isinstance(total_in, int)
|
||||||
|
assert isinstance(total_out, int)
|
||||||
return total_in + mint - total_out
|
return total_in + mint - total_out
|
||||||
|
|
||||||
async def verify(
|
async def verify(
|
||||||
@ -230,6 +239,8 @@ class TransactionData(RecursiveMentionable, StaticMentionable):
|
|||||||
self.in_coins.str(tab),
|
self.in_coins.str(tab),
|
||||||
self.out_coins.str(tab),
|
self.out_coins.str(tab),
|
||||||
)
|
)
|
||||||
|
assert isinstance(in_str, str)
|
||||||
|
assert isinstance(out_str, str)
|
||||||
return f'(in)' \
|
return f'(in)' \
|
||||||
f'{tabulate(tab)}{in_str}' \
|
f'{tabulate(tab)}{in_str}' \
|
||||||
f'{tabulate(tab)}(out)' \
|
f'{tabulate(tab)}(out)' \
|
||||||
@ -276,6 +287,8 @@ class Transaction(RecursiveMentionable, StaticMentionable):
|
|||||||
mint: int,
|
mint: int,
|
||||||
miner: Nullable[HashPoint[Subject]]
|
miner: Nullable[HashPoint[Subject]]
|
||||||
) -> AsyncIterable[tuple[Coin, Nullable[HashPoint[Subject]]]]:
|
) -> AsyncIterable[tuple[Coin, Nullable[HashPoint[Subject]]]]:
|
||||||
|
assert isinstance(mint, int)
|
||||||
|
assert isinstance(miner, Nullable)
|
||||||
transaction_data: TransactionData = await self.data_resolved()
|
transaction_data: TransactionData = await self.data_resolved()
|
||||||
assert isinstance(transaction_data, TransactionData)
|
assert isinstance(transaction_data, TransactionData)
|
||||||
index = 0
|
index = 0
|
||||||
@ -325,6 +338,8 @@ class Transaction(RecursiveMentionable, StaticMentionable):
|
|||||||
hash_point_format(self.data, tab + 1),
|
hash_point_format(self.data, tab + 1),
|
||||||
self.signatures.str(tab + 1),
|
self.signatures.str(tab + 1),
|
||||||
)
|
)
|
||||||
|
assert isinstance(data_str, str)
|
||||||
|
assert isinstance(signatures_str, str)
|
||||||
return f'(' \
|
return f'(' \
|
||||||
f'{tabulate(tab + 1)}transaction' \
|
f'{tabulate(tab + 1)}transaction' \
|
||||||
f'{tabulate(tab + 1)}{data_str}' \
|
f'{tabulate(tab + 1)}{data_str}' \
|
||||||
@ -338,6 +353,9 @@ class Transaction(RecursiveMentionable, StaticMentionable):
|
|||||||
out_coins: list[CoinData],
|
out_coins: list[CoinData],
|
||||||
keys: list[nacl.signing.SigningKey],
|
keys: list[nacl.signing.SigningKey],
|
||||||
) -> 'Transaction':
|
) -> 'Transaction':
|
||||||
|
assert isinstance(in_coins, list)
|
||||||
|
assert isinstance(out_coins, list)
|
||||||
|
assert isinstance(keys, list)
|
||||||
transaction_data = TransactionData(
|
transaction_data = TransactionData(
|
||||||
Stack.off(Coin.factory(), reversed(in_coins)),
|
Stack.off(Coin.factory(), reversed(in_coins)),
|
||||||
Stack.off(CoinData.factory(), reversed(out_coins)),
|
Stack.off(CoinData.factory(), reversed(out_coins)),
|
||||||
|
@ -271,12 +271,19 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable):
|
|||||||
for key_index in range(self.keys):
|
for key_index in range(self.keys):
|
||||||
yield self.key_no(key_index)
|
yield self.key_no(key_index)
|
||||||
else:
|
else:
|
||||||
|
children: list[WeakReferenceIndexSetBTree] = list(
|
||||||
|
await gather(
|
||||||
|
*(
|
||||||
|
self.child_resolved_no(child) for child in range(self.children)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
for index in range(self.keys * 2 + 1):
|
for index in range(self.keys * 2 + 1):
|
||||||
real_index, mode = divmod(index, 2)
|
real_index, mode = divmod(index, 2)
|
||||||
if mode:
|
if mode:
|
||||||
yield self.key_no(real_index)
|
yield self.key_no(real_index)
|
||||||
else:
|
else:
|
||||||
async for key in (await self.child_resolved_no(real_index)).iter_keys():
|
async for key in children[real_index].iter_keys():
|
||||||
yield key
|
yield key
|
||||||
|
|
||||||
|
|
||||||
|
106
trace.py
Normal file
106
trace.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import asyncio
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import shutil
|
||||||
|
import time
|
||||||
|
from contextlib import ExitStack
|
||||||
|
|
||||||
|
from nacl.signing import SigningKey
|
||||||
|
|
||||||
|
from plot import plot
|
||||||
|
from rainbowadn.chain import *
|
||||||
|
from rainbowadn.collection.trees.binary import *
|
||||||
|
from rainbowadn.core import *
|
||||||
|
from rainbowadn.nullability import *
|
||||||
|
from rainbowadn.testing.instrumentation import *
|
||||||
|
from rainbowadn.testing.resolvers import *
|
||||||
|
from rainbowadn.v13 import *
|
||||||
|
|
||||||
|
|
||||||
|
def get_dr() -> ExtendableResolver:
|
||||||
|
dr = DictResolver()
|
||||||
|
dr = DelayedResolver(dr, lambda: random.uniform(0.200, 0.500))
|
||||||
|
# dr = CachingResolver(dr)
|
||||||
|
return dr
|
||||||
|
|
||||||
|
|
||||||
|
def target_str(target) -> str:
|
||||||
|
match target:
|
||||||
|
case type(__name__=name):
|
||||||
|
return name
|
||||||
|
case object(__class__=type(__name__=name)):
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
def jsonify(instrumentation: Instrumentation) -> dict:
|
||||||
|
prefix = f'{target_str(instrumentation.target)}:{instrumentation.methodname}'
|
||||||
|
match instrumentation:
|
||||||
|
case Counter(counter=counter):
|
||||||
|
return {f'{prefix}:counter': counter}
|
||||||
|
case Concurrency(log=log):
|
||||||
|
return {f'{prefix}:concurrency': log}
|
||||||
|
case EntryExit(entry_log=entry_log, exit_log=exit_log):
|
||||||
|
return {
|
||||||
|
f'{prefix}:entry': entry_log,
|
||||||
|
f'{prefix}:exit': exit_log,
|
||||||
|
}
|
||||||
|
case _:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
set_gather_linear()
|
||||||
|
bank: BankChain = BankChain.empty(ReductionChainMetaFactory().loose())
|
||||||
|
key_0 = SigningKey.generate()
|
||||||
|
transaction_0 = Transaction.make(
|
||||||
|
[],
|
||||||
|
[CoinData.of(Subject(key_0.verify_key), 100_000)],
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
coin_0, coin_1 = await transaction_0.coins(MINT_CONST, NotNull(HashPoint.of(Subject(key_0.verify_key))))
|
||||||
|
bank = await bank.adds(
|
||||||
|
[
|
||||||
|
transaction_0,
|
||||||
|
Transaction.make(
|
||||||
|
[coin_1],
|
||||||
|
[CoinData.of(Subject(SigningKey.generate().verify_key), 10_000)],
|
||||||
|
[key_0]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
for _ in range(16):
|
||||||
|
bank = await bank.adds(
|
||||||
|
[
|
||||||
|
Transaction.make(
|
||||||
|
[],
|
||||||
|
[CoinData.of(Subject(SigningKey.generate().verify_key), 0)] * 16,
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
for _ in range(16)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
print('built')
|
||||||
|
assert_true(await bank.verify())
|
||||||
|
bank = BankChain.from_reference(
|
||||||
|
ReductionChainMetaFactory(), await get_dr().migrate_resolved(bank.reference)
|
||||||
|
)
|
||||||
|
print('saved')
|
||||||
|
set_gather_asyncio()
|
||||||
|
with ExitStack() as stack:
|
||||||
|
sleep_cc = Concurrency(DelayedResolver, 'sleep').enter(stack)
|
||||||
|
avl_ex = EntryExit(ActiveBinaryTree, 'add', sleep_cc.point).enter(stack)
|
||||||
|
assert_true(await bank.verify())
|
||||||
|
print(Instrumentation.deinstrumentation)
|
||||||
|
fn = f'trace/{int(time.time())}-{os.urandom(2).hex()}.json'
|
||||||
|
with open(fn, 'w') as file:
|
||||||
|
json.dump(
|
||||||
|
jsonify(sleep_cc) | jsonify(avl_ex),
|
||||||
|
file
|
||||||
|
)
|
||||||
|
shutil.copy(fn, f'trace/latest.json')
|
||||||
|
plot()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
asyncio.run(main())
|
Loading…
Reference in New Issue
Block a user