-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtransaction_pool.py
More file actions
60 lines (49 loc) · 2.25 KB
/
transaction_pool.py
File metadata and controls
60 lines (49 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# pyncoin/transaction_pool.py
from transaction import Transaction
from utils import RawSerializable, BadRequestError
class TransactionPool(RawSerializable):
def __init__(self):
self.transactions = []
def add_transaction(self, transaction, unspent_tx_outs):
if not transaction.validate(unspent_tx_outs) or not self.is_valid_transaction(transaction):
return False
print('adding to tx_pool: {}'.format(transaction))
self.transactions.append(transaction)
return True
def ins(self):
''' Returns the transaction inputs in this pool. '''
return [tx_in for tx in self.transactions for tx_in in tx.tx_ins]
@staticmethod
def has_tx_in(tx_in, unspent_tx_outs):
return next((uTxO for uTxO in unspent_tx_outs if uTxO.matches_tx_in(tx_in)), None) is not None
def is_valid_transaction(self, transaction):
pool_ins = self.ins()
for tx_in in transaction.tx_ins:
if tx_in in pool_ins:
print('tx_in already found in the tx_pool')
return False
return True
def update(self, unspent_tx_outs):
invalid_txs = []
for tx in self.transactions:
for tx_in in tx.tx_ins:
if not TransactionPool.has_tx_in(tx_in, unspent_tx_outs):
invalid_txs.append(tx)
break
if invalid_txs:
print('removing the following transactions from tx_pool: {}'.format(invalid_txs))
self.transactions = [tx for tx in self.transactions if tx not in invalid_txs]
def to_raw(self):
return Transaction.to_raw_list(self.transactions)
def filtered_unspent_tx_outs(self, unspent_tx_outs):
tx_ins = [tx_in for tx in self.transactions for tx_in in tx.tx_ins]
removable = []
for unspent_tx_out in unspent_tx_outs:
tx_in = next((tx_in for tx_in in tx_ins if unspent_tx_out.matches_tx_in(tx_in)), None)
if tx_in is not None:
removable.append(unspent_tx_out)
remaining = [uTxO for uTxO in unspent_tx_outs if uTxO not in removable]
return remaining
@classmethod
def from_raw(cls, raw_obj):
raise AssertionError('Transaction pool must not be created from raw values.')