Stack.iter
This commit is contained in:
parent
2f0650cf69
commit
97fd1105d0
@ -68,6 +68,19 @@ class Stack(RecursiveMentionable, Generic[ElementType]):
|
||||
assert isinstance(factory, RainbowFactory)
|
||||
return cls.of(factory, map(HashPoint.of, elements))
|
||||
|
||||
@classmethod
|
||||
def iter(
|
||||
cls,
|
||||
reference: NullableReference['Stack[ElementType]']
|
||||
) -> Iterable[HashPoint[ElementType]]:
|
||||
assert isinstance(reference, NullableReference)
|
||||
if reference.reference.null():
|
||||
pass
|
||||
else:
|
||||
stack: Stack[ElementType] = reference.reference.resolve().resolve()
|
||||
yield stack.element
|
||||
yield from cls.iter(stack.previous)
|
||||
|
||||
|
||||
class StackFactory(RainbowFactory[Stack[ElementType]], Generic[ElementType]):
|
||||
def __init__(self, factory: RainbowFactory[ElementType]):
|
||||
|
@ -30,6 +30,7 @@ from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot
|
||||
|
||||
|
||||
class TestAll(unittest.TestCase):
|
||||
"""examples rather than real tests"""
|
||||
def test_bankchain(self):
|
||||
with self.subTest('setup'):
|
||||
dr = DictResolver()
|
||||
|
@ -19,7 +19,7 @@ from rainbowadn.hashing.resolverorigin import ResolverOrigin
|
||||
from rainbowadn.hashing.static import StaticFactory, StaticMentionable
|
||||
from rainbowadn.v13.algo import MINT_CONST
|
||||
from rainbowadn.v13.subject import Subject
|
||||
from rainbowadn.v13.transaction import Coin, Transaction, TransactionData
|
||||
from rainbowadn.v13.transaction import Coin, Transaction
|
||||
|
||||
__all__ = ('BankState',)
|
||||
|
||||
@ -87,55 +87,63 @@ class BankState(RecursiveMentionable, StaticMentionable):
|
||||
HashPoint.of(Integer(self.length.resolve().integer + 1))
|
||||
)
|
||||
|
||||
def push(self, transaction: HashPoint[Transaction]) -> 'BankState':
|
||||
assert isinstance(transaction, HashPoint)
|
||||
|
||||
transaction_resolved = transaction.resolve()
|
||||
assert isinstance(transaction_resolved, Transaction)
|
||||
|
||||
miner: Nullable[HashPoint[Subject]] = self.miner.reference
|
||||
assert isinstance(miner, Nullable)
|
||||
if miner.null():
|
||||
mint = MINT_CONST
|
||||
else:
|
||||
mint = 0
|
||||
|
||||
assert transaction_resolved.verify(mint)
|
||||
transaction_data: TransactionData = transaction_resolved.data.resolve()
|
||||
assert isinstance(transaction_data, TransactionData)
|
||||
|
||||
minted: ActiveBinaryTree[Coin, Integer] = ActiveBinaryTree(
|
||||
def minted_tree(self) -> ActiveBinaryTree[Coin, Integer]:
|
||||
return ActiveBinaryTree(
|
||||
AVLBTBP(HashComparator(Fail())), self.minted
|
||||
)
|
||||
assert isinstance(minted, ActiveBinaryTree)
|
||||
used: ActiveBinaryTree[Coin, Integer] = ActiveBinaryTree(
|
||||
|
||||
def used_tree(self) -> ActiveBinaryTree[Coin, Integer]:
|
||||
return ActiveBinaryTree(
|
||||
AVLBTBP(HashComparator(Fail())), self.used
|
||||
)
|
||||
assert isinstance(used, ActiveBinaryTree)
|
||||
|
||||
in_coin: HashPoint[Coin]
|
||||
for in_coin in transaction_data.iter_in_coins():
|
||||
assert isinstance(in_coin, HashPoint)
|
||||
def use_coins(self, coins: Iterable[HashPoint[Coin]]) -> 'BankState':
|
||||
minted: ActiveBinaryTree[Coin, Integer] = self.minted_tree()
|
||||
used: ActiveBinaryTree[Coin, Integer] = self.used_tree()
|
||||
for in_coin in coins:
|
||||
assert not minted.query_tree().query(in_coin).null()
|
||||
assert used.query_tree().query(in_coin).null()
|
||||
used = used.add(in_coin)
|
||||
assert isinstance(used, ActiveBinaryTree)
|
||||
return BankState(self.minted, used.reference, self.miner, self.length)
|
||||
|
||||
coin: Coin
|
||||
for coin, miner in transaction_resolved.iter_coins(mint, miner):
|
||||
assert isinstance(coin, Coin)
|
||||
assert isinstance(miner, Nullable)
|
||||
def mint_coins(
|
||||
self,
|
||||
transaction: Transaction
|
||||
) -> 'BankState':
|
||||
assert self.verify(transaction)
|
||||
miner = self.miner_nullable()
|
||||
minted: ActiveBinaryTree[Coin, Integer] = self.minted_tree()
|
||||
for coin, miner in transaction.iter_coins(self.mint(), miner):
|
||||
assert minted.query_tree().query(HashPoint.of(coin)).null()
|
||||
minted = minted.add(HashPoint.of(coin))
|
||||
assert isinstance(minted, ActiveBinaryTree)
|
||||
return BankState(minted.reference, self.used, NullableReference(miner, self.miner.factory), self.length)
|
||||
|
||||
return BankState(
|
||||
minted.reference,
|
||||
used.reference,
|
||||
NullableReference(miner, self.miner.factory),
|
||||
self.length
|
||||
def miner_nullable(self) -> Nullable[HashPoint[Subject]]:
|
||||
return self.miner.reference
|
||||
|
||||
def mint(self) -> int:
|
||||
if self.miner_nullable().null():
|
||||
return MINT_CONST
|
||||
else:
|
||||
return 0
|
||||
|
||||
def verify(self, transaction: Transaction) -> bool:
|
||||
assert isinstance(transaction, Transaction)
|
||||
assert transaction.verify(self.mint())
|
||||
return True
|
||||
|
||||
def _push(self, transaction: Transaction) -> 'BankState':
|
||||
assert isinstance(transaction, Transaction)
|
||||
return self.use_coins(
|
||||
transaction.data.resolve().iter_in_coins()
|
||||
).mint_coins(
|
||||
transaction
|
||||
)
|
||||
|
||||
def push(self, transaction: HashPoint[Transaction]) -> 'BankState':
|
||||
return self._push(transaction.resolve())
|
||||
|
||||
def str(self, tab: int) -> str:
|
||||
assert isinstance(tab, int)
|
||||
return f'(' \
|
||||
|
@ -137,73 +137,26 @@ class TransactionData(RecursiveMentionable, StaticMentionable):
|
||||
|
||||
def _verify_signatures(
|
||||
self,
|
||||
in_coins: NullableReference[Stack[Coin]],
|
||||
signatures: NullableReference[Stack[Signature]],
|
||||
signatures: NullableReference[Stack[Signature]]
|
||||
) -> bool:
|
||||
assert isinstance(in_coins, NullableReference)
|
||||
assert isinstance(signatures, NullableReference)
|
||||
if in_coins.reference.null():
|
||||
assert signatures.reference.null()
|
||||
return True
|
||||
else:
|
||||
assert not signatures.reference.null()
|
||||
in_coins_stack: Stack[Coin] = in_coins.reference.resolve().resolve()
|
||||
assert isinstance(in_coins_stack, Stack)
|
||||
signatures_stack: Stack[Signature] = signatures.reference.resolve().resolve()
|
||||
assert isinstance(signatures_stack, Stack)
|
||||
coin: Coin = in_coins_stack.element.resolve()
|
||||
assert isinstance(coin, Coin)
|
||||
coin_data: CoinData = coin.data.resolve()
|
||||
assert isinstance(coin_data, CoinData)
|
||||
owner: Subject = coin_data.owner.resolve()
|
||||
assert isinstance(owner, Subject)
|
||||
signature: Signature = signatures_stack.element.resolve()
|
||||
assert isinstance(signature, Signature)
|
||||
assert signature.verify(owner, self.hash_point)
|
||||
assert self._verify_signatures(in_coins_stack.previous, signatures_stack.previous)
|
||||
return True
|
||||
for coin, signature in zip(self.iter_in_coins(), Stack.iter(signatures), strict=True):
|
||||
assert signature.resolve().verify(
|
||||
coin.resolve().data.resolve().owner.resolve(),
|
||||
self.hash_point
|
||||
)
|
||||
return True
|
||||
|
||||
def iter_in_coins(self) -> Iterable[HashPoint[Coin]]:
|
||||
in_coins: NullableReference[Stack[Coin]] = self.in_coins
|
||||
assert isinstance(in_coins, NullableReference)
|
||||
while not in_coins.reference.null():
|
||||
in_coins_stack: Stack[Coin] = in_coins.reference.resolve().resolve()
|
||||
assert isinstance(in_coins_stack, Stack)
|
||||
coin: HashPoint[Coin] = in_coins_stack.element
|
||||
assert isinstance(coin, HashPoint)
|
||||
yield coin
|
||||
in_coins = in_coins_stack.previous
|
||||
assert isinstance(in_coins, NullableReference)
|
||||
assert in_coins.reference.null()
|
||||
return Stack.iter(self.in_coins)
|
||||
|
||||
def _total_in(self) -> int:
|
||||
total_in = 0
|
||||
coin: HashPoint[Coin]
|
||||
for coin in self.iter_in_coins():
|
||||
assert isinstance(coin, HashPoint)
|
||||
total_in += coin.resolve().data.resolve().value.resolve().integer
|
||||
return total_in
|
||||
return sum(coin.resolve().data.resolve().value.resolve().integer for coin in self.iter_in_coins())
|
||||
|
||||
def iter_out_coins(self) -> Iterable[HashPoint[CoinData]]:
|
||||
out_coins: NullableReference[Stack[CoinData]] = self.out_coins
|
||||
assert isinstance(out_coins, NullableReference)
|
||||
while not out_coins.reference.null():
|
||||
out_coins_stack: Stack[CoinData] = out_coins.reference.resolve().resolve()
|
||||
assert isinstance(out_coins_stack, Stack)
|
||||
coin: HashPoint[CoinData] = out_coins_stack.element
|
||||
assert isinstance(coin, HashPoint)
|
||||
yield coin
|
||||
out_coins = out_coins_stack.previous
|
||||
assert isinstance(out_coins, NullableReference)
|
||||
assert out_coins.reference.null()
|
||||
return Stack.iter(self.out_coins)
|
||||
|
||||
def _total_out(self) -> int:
|
||||
total_out = 0
|
||||
coin: HashPoint[CoinData]
|
||||
for coin in self.iter_out_coins():
|
||||
assert isinstance(coin, HashPoint)
|
||||
total_out += coin.resolve().value.resolve().integer
|
||||
return total_out
|
||||
return sum(coin.resolve().value.resolve().integer for coin in self.iter_out_coins())
|
||||
|
||||
def _verify_values(self, mint: int) -> bool:
|
||||
assert isinstance(mint, int)
|
||||
@ -221,7 +174,9 @@ class TransactionData(RecursiveMentionable, StaticMentionable):
|
||||
) -> bool:
|
||||
assert isinstance(signatures, NullableReference)
|
||||
assert isinstance(mint, int)
|
||||
return self._verify_signatures(self.in_coins, signatures) and self._verify_values(mint)
|
||||
assert self._verify_signatures(signatures)
|
||||
assert self._verify_values(mint)
|
||||
return True
|
||||
|
||||
def str(self, tab: int) -> str:
|
||||
assert isinstance(tab, int)
|
||||
@ -308,7 +263,8 @@ class Transaction(RecursiveMentionable, StaticMentionable):
|
||||
assert isinstance(mint, int)
|
||||
data: TransactionData = self.data.resolve()
|
||||
assert isinstance(data, TransactionData)
|
||||
return data.verify(self.signatures, mint)
|
||||
assert data.verify(self.signatures, mint)
|
||||
return True
|
||||
|
||||
def __str__(self):
|
||||
return f'(transaction)'
|
||||
|
Loading…
Reference in New Issue
Block a user