Skip to content

Commit

Permalink
Do not refresh data older than 1 month
Browse files Browse the repository at this point in the history
  • Loading branch information
Insoleet committed Aug 8, 2018
1 parent 0c0c6d2 commit 2964ea7
Show file tree
Hide file tree
Showing 13 changed files with 257 additions and 351 deletions.
29 changes: 28 additions & 1 deletion src/sakia/data/entities/transaction.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import attr
import hashlib
from duniterpy.documents import block_uid
from duniterpy.documents import block_uid, BlockUID
from duniterpy.documents import Transaction as TransactionDoc
from duniterpy.documents.transaction import reduce_base
from sakia.helpers import attrs_tuple_of_str
Expand All @@ -9,6 +9,7 @@

STOPLINE_HASH = hashlib.sha256("STOPLINE".encode("UTF-8")).hexdigest()


def parse_transaction_doc(tx_doc, pubkey, block_number, mediantime, txid):
"""
Parse a transaction
Expand Down Expand Up @@ -73,6 +74,32 @@ def parse_transaction_doc(tx_doc, pubkey, block_number, mediantime, txid):
raw=tx_doc.signed_raw())
return transaction


STOPLINE_HASH = hashlib.sha256("STOPLINE".encode("UTF-8")).hexdigest()


def build_stopline(currency, pubkey, block_number, mediantime):
"""
Used to insert a line of ignored tx in the history
"""
transaction = Transaction(currency=currency,
pubkey=pubkey,
sha_hash=STOPLINE_HASH,
written_block=block_number,
blockstamp=BlockUID(block_number, BlockUID.empty().sha_hash),
timestamp=mediantime,
signatures="",
issuers="",
receivers="",
amount=0,
amount_base=0,
comment="",
txid=0,
state=Transaction.VALIDATED,
raw="")
return transaction


@attr.s(hash=True)
class Transaction:
"""
Expand Down
76 changes: 39 additions & 37 deletions src/sakia/data/processors/blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ def rounded_timestamp(self, currency, block_number):
diff_time = diff_blocks * parameters.avg_gen_time
return current_time + diff_time

def block_number_30days_ago(self, currency, blockstamp):
"""
When refreshing data, we only request the last 30 days
This method computes the block number 30 days ago
:param currency:
:return:
"""
avg_blocks_per_month = int(30 * 24 * 3600 / self.parameters(currency).avg_gen_time)
return blockstamp.number - avg_blocks_per_month

def current_buid(self, currency):
"""
Expand Down Expand Up @@ -231,22 +240,6 @@ async def new_blocks_with_money(self, currency):
local_current_buid = self.current_buid(currency)
return sorted([b for b in with_money if b > local_current_buid.number])

async def next_blocks(self, start, filter, currency):
"""
Get blocks from the network
:param List[int] numbers: list of blocks numbers to get
:return: the list of block documents
:rtype: List[duniterpy.documents.Block]
"""
blocks = []
blocks_data = await self._bma_connector.get(currency, bma.blockchain.blocks, req_args={'count': 100,
'start': start})
for data in blocks_data:
if data['number'] in filter or data['number'] == start+99:
blocks.append(Block.from_signed_raw(data["raw"] + data["signature"] + "\n"))

return blocks

async def initialize_blockchain(self, currency):
"""
Initialize blockchain for a given currency if no source exists locally
Expand Down Expand Up @@ -353,30 +346,39 @@ async def initialize_blockchain(self, currency):
except sqlite3.IntegrityError:
self._repo.update(blockchain)

def handle_new_blocks(self, currency, blocks):
async def handle_new_blocks(self, currency, network_blockstamp):
"""
Initialize blockchain for a given currency if no source exists locally
:param List[duniterpy.documents.Block] blocks
:param str currency:
:param BlockUID network_blockstamp: the blockstamp of the network
"""
blockchain = self._repo.get_one(currency=currency)
for block in sorted(blocks):
if blockchain.current_buid < block.blockUID:
blockchain.current_buid = block.blockUID
blockchain.median_time = block.mediantime
blockchain.current_members_count = block.members_count
if block.ud:
blockchain.current_mass += (block.ud * 10**block.unit_base) * block.members_count
if block.ud and blockchain.last_ud_time + blockchain.parameters.dt_reeval >= block.mediantime:
blockchain.previous_mass = blockchain.last_mass
blockchain.previous_members_count = blockchain.last_members_count
blockchain.previous_ud = blockchain.last_ud
blockchain.previous_ud_base = blockchain.last_ud_base
blockchain.previous_ud_time = blockchain.last_ud_time
blockchain.last_members_count = block.members_count
blockchain.last_ud = block.ud
blockchain.last_ud_base = block.unit_base
blockchain.last_ud_time = block.mediantime
self._repo.update(blockchain)

self._logger.debug("Requesting current block")
try:
current_block = await self._bma_connector.get(currency, bma.blockchain.block,
req_args={'number': network_blockstamp.number})
signed_raw = "{0}{1}\n".format(current_block['raw'], current_block['signature'])
block = Block.from_signed_raw(signed_raw)
blockchain = self._repo.get_one(currency=currency)
blockchain.current_buid = block.blockUID
blockchain.median_time = block.mediantime
blockchain.current_members_count = block.members_count
if block.ud:
blockchain.current_mass += (block.ud * 10**block.unit_base) * block.members_count
if block.ud and blockchain.last_ud_time + blockchain.parameters.dt_reeval >= block.mediantime:
blockchain.previous_mass = blockchain.last_mass
blockchain.previous_members_count = blockchain.last_members_count
blockchain.previous_ud = blockchain.last_ud
blockchain.previous_ud_base = blockchain.last_ud_base
blockchain.previous_ud_time = blockchain.last_ud_time
blockchain.last_members_count = block.members_count
blockchain.last_ud = block.ud
blockchain.last_ud_base = block.unit_base
blockchain.last_ud_time = block.mediantime
self._repo.update(blockchain)
except errors.DuniterError as e:
if e.ucode != errors.NO_CURRENT_BLOCK:
raise

def remove_blockchain(self, currency):
self._repo.drop(self._repo.get_one(currency=currency))
Expand Down
19 changes: 10 additions & 9 deletions src/sakia/data/processors/tx_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
from duniterpy.documents import Block


def _found_in_block(tx, block):
def _found_in_block(tx, sha_hash, block_number):
"""
Check if the transaction can be found in the blockchain
:param sakia.data.entities.Transaction tx: the transaction
:param duniterpy.documents.Block block: The block to check for the transaction
:param str sha_hash: The transaction sha_hash found in history
:param int block_number: The block_number where the tx was found
:return: True if the transaction was found
:rtype: bool
"""
for block_tx in block.transactions:
if block_tx.sha_hash == tx.sha_hash:
return True
if sha_hash == tx.sha_hash:
return True


def _broadcast_success(tx, ret_codes):
Expand Down Expand Up @@ -49,15 +49,16 @@ def _is_locally_created(tx):
return tx.local


def _be_validated(tx, block):
def _be_validated(tx, sha_hash, block_number):
"""
Action when the transfer ins found in a block
:param sakia.data.entities.Transaction tx: the transaction
:param bool rollback: True if we are in a rollback procedure
:param duniterpy.documents.Block block: The block checked
:param str sha_hash: The tx sha_hash found in history
:param int block_number: The block_number where the tx was found
"""
tx.written_block = block.number
tx.written_block = block_number


def _drop(tx):
Expand All @@ -81,7 +82,7 @@ def _drop(tx):
(Transaction.TO_SEND, ()):
((_is_locally_created, _drop, Transaction.DROPPED),),

(Transaction.AWAITING, (Block,)):
(Transaction.AWAITING, (str, int,)):
((_found_in_block, _be_validated, Transaction.VALIDATED),),

(Transaction.REFUSED, ()):
Expand Down
20 changes: 11 additions & 9 deletions src/sakia/gui/navigation/txhistory/sql_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
AND transactions.ts >= ?
and transactions.ts <= ?
AND transactions.issuers LIKE "%{pubkey}%"
UNION ALL
SELECT
transactions.ts,
Expand All @@ -35,7 +36,8 @@
and transactions.pubkey = ?
AND transactions.ts >= ?
and transactions.ts <= ?
AND transactions.receivers LIKE "%{pubkey}%"
AND (transactions.receivers LIKE "%{pubkey}%"
OR transactions.sha_hash = ?)
UNION ALL
SELECT
dividends.timestamp as ts,
Expand All @@ -61,7 +63,7 @@
class TxHistorySqlAdapter:
_conn = attr.ib() # :type sqlite3.Connection

def _transfers_and_dividends(self, currency, pubkey, ts_from, ts_to, offset=0, limit=1000,
def _transfers_and_dividends(self, currency, pubkey, ts_from, ts_to, stopline_hash, offset=0, limit=1000,
sort_by="currency", sort_order="ASC"):
"""
Get all transfers in the database on a given currency from or to a pubkey
Expand All @@ -78,14 +80,14 @@ def _transfers_and_dividends(self, currency, pubkey, ts_from, ts_to, offset=0, l
pubkey=pubkey
)
c = self._conn.execute(request, (currency, pubkey, ts_from, ts_to,
currency, pubkey, ts_from, ts_to,
currency, pubkey, ts_from, ts_to, stopline_hash,
currency, pubkey, ts_from, ts_to))
datas = c.fetchall()
if datas:
return datas
return []

def _transfers_and_dividends_count(self, currency, pubkey, ts_from, ts_to):
def _transfers_and_dividends_count(self, currency, pubkey, ts_from, ts_to, stopline_hash):
"""
Get all transfers in the database on a given currency from or to a pubkey
Expand All @@ -97,14 +99,14 @@ def _transfers_and_dividends_count(self, currency, pubkey, ts_from, ts_to):
FROM (
""" + TX_HISTORY_REQUEST + ")").format(pubkey=pubkey)
c = self._conn.execute(request, (currency, pubkey, ts_from, ts_to,
currency, pubkey, ts_from, ts_to,
currency, pubkey, ts_from, ts_to, stopline_hash,
currency, pubkey, ts_from, ts_to))
datas = c.fetchone()
if datas:
return datas[0]
return 0

def transfers_and_dividends(self, currency, pubkey, page, ts_from, ts_to, sort_by, sort_order):
def transfers_and_dividends(self, currency, pubkey, page, ts_from, ts_to, stopline_hash, sort_by, sort_order):
"""
Get all transfers and dividends from or to a given pubkey
:param str currency:
Expand All @@ -115,12 +117,12 @@ def transfers_and_dividends(self, currency, pubkey, page, ts_from, ts_to, sort_b
:return: the list of Transaction entities
:rtype: List[sakia.data.entities.Transaction]
"""
return self._transfers_and_dividends(currency, pubkey, ts_from, ts_to,
return self._transfers_and_dividends(currency, pubkey, ts_from, ts_to, stopline_hash,
offset=page*PAGE_LENGTH,
limit=PAGE_LENGTH,
sort_by=sort_by, sort_order=sort_order)

def pages(self, currency, pubkey, ts_from, ts_to):
def pages(self, currency, pubkey, ts_from, ts_to, stopline_hash):
"""
Get all transfers and dividends from or to a given pubkey
:param str currency:
Expand All @@ -131,7 +133,7 @@ def pages(self, currency, pubkey, ts_from, ts_to):
:return: the list of Transaction entities
:rtype: List[sakia.data.entities.Transaction]
"""
count = self._transfers_and_dividends_count(currency, pubkey, ts_from, ts_to)
count = self._transfers_and_dividends_count(currency, pubkey, ts_from, ts_to, stopline_hash)
return int(count / PAGE_LENGTH)


Loading

0 comments on commit 2964ea7

Please sign in to comment.