# Path: database.py
# def txn_required(func):
#     @functools.wraps(func)
#     def _func(*args, **kwargs):
#         txn = current_txn()
#         if txn:
#             return func(*args, **kwargs)
#         else:
#             return run_in_transaction(func, txn_name=func.__name__, *args, **kwargs)
#     return _func
# 
# class TxnAbort(Exception):
#     def __init__(self, callback=None, *args, **kwargs):
#         self.__callback = callback
#         self.__args = args
#         self.__kwargs = kwargs
#         
#     @property
#     def callback(self):
#         if self.__callback:
#             return lambda: self.__callback(*self.__args, **self.__kwargs)
#         else:
#             return None
#             
#     def __call__(self):
#         cb = self.callback
#         if cb: return cb()
# 
# @contextmanager
# def Transaction(name="*UNKNOWN*", flags=DEFAULT_TXN_FLAGS):
#         txn = begin_txn(flags)
#         txn.set_name(name)
#         txn_log.debug("TXN BEGIN %s", repr(txn))
#         try:
#             yield txn
#         except Exception as e:
#             txn_log.debug("TXN ABORT %s", repr(txn)) 
#             abort_txn()
#             raise
#         txn_log.debug("TXN COMMIT %s", repr(txn))
#         commit_txn()


import eventlet
import genesisblock
import msgs
import jserialize as js
import bserialize as bs
import logging
import settings
import database
import transactions
import struct
    import sys
    import time
        import debug
from utils import *
from database import txn_required, TxnAbort, Transaction
        if enum:
            for blkidx, tx_h in sl:
                yield (blkidx, transactions.Tx.get_by_hash(tx_h))
        else:
            for blkidx, tx_h in sl:
                yield transactions.Tx.get_by_hash(tx_h)
                
    def get_prev(self):
        return Block.get_by_hash(self.prev)
        
    def get_next_bits(self):
        targettimespan = 14 * 24 * 60 * 60 # 2 weeks in secounds
        spacing = 10 * 60 # 10 min in secounds
        interval = targettimespan/spacing # 2 weeks of blocks(2016)
        if (self.number + 1) % interval != 0:
            return self.block.bits
        log.info("DIFF: retarget, current bits: %s", hex(self.block.bits))
        first_blk = self
        for i in range(interval-1):
            first_blk = first_blk.get_prev()
        realtimespan = self.block.time - first_blk.block.time
        log.info("DIFF: timespan before limits: %d", realtimespan)
        if realtimespan < targettimespan/4: realtimespan = targettimespan/4
        if realtimespan > targettimespan*4: realtimespan = targettimespan*4
        log.info("DIFF: timespan after limits: %d", realtimespan)
        newtarget = (bits_to_target(self.block.bits)*realtimespan)/targettimespan
        if newtarget > bits_to_target(0x1d00ffff):
            newtarget = bits_to_target(0x1d00ffff)
        bits = target_to_bits(newtarget)
        log.info("DIFF: next bits: %s", hex(bits))

# Path: database.py
# def txn_required(func):
#     @functools.wraps(func)
#     def _func(*args, **kwargs):
#         txn = current_txn()
#         if txn:
#             return func(*args, **kwargs)
#         else:
#             return run_in_transaction(func, txn_name=func.__name__, *args, **kwargs)
#     return _func
# 
# class TxnAbort(Exception):
#     def __init__(self, callback=None, *args, **kwargs):
#         self.__callback = callback
#         self.__args = args
#         self.__kwargs = kwargs
#         
#     @property
#     def callback(self):
#         if self.__callback:
#             return lambda: self.__callback(*self.__args, **self.__kwargs)
#         else:
#             return None
#             
#     def __call__(self):
#         cb = self.callback
#         if cb: return cb()
# 
# @contextmanager
# def Transaction(name="*UNKNOWN*", flags=DEFAULT_TXN_FLAGS):
#         txn = begin_txn(flags)
#         txn.set_name(name)
#         txn_log.debug("TXN BEGIN %s", repr(txn))
#         try:
#             yield txn
#         except Exception as e:
#             txn_log.debug("TXN ABORT %s", repr(txn)) 
#             abort_txn()
#             raise
#         txn_log.debug("TXN COMMIT %s", repr(txn))
#         commit_txn()


# Path: blockchain.py
import eventlet
import genesisblock
import msgs
import jserialize as js
import bserialize as bs
import logging
import settings
import database
import transactions
import struct
    import sys
    import time
        import debug
from utils import *
from database import txn_required, TxnAbort, Transaction

        if enum:
            for blkidx, tx_h in sl:
                yield (blkidx, transactions.Tx.get_by_hash(tx_h))
        else:
            for blkidx, tx_h in sl:
                yield transactions.Tx.get_by_hash(tx_h)
                
    def get_prev(self):
        return Block.get_by_hash(self.prev)
        
    def get_next_bits(self):
        targettimespan = 14 * 24 * 60 * 60 # 2 weeks in secounds
        spacing = 10 * 60 # 10 min in secounds
        interval = targettimespan/spacing # 2 weeks of blocks(2016)
        if (self.number + 1) % interval != 0:
            return self.block.bits
        log.info("DIFF: retarget, current bits: %s", hex(self.block.bits))
        first_blk = self
        for i in range(interval-1):
            first_blk = first_blk.get_prev()
        realtimespan = self.block.time - first_blk.block.time
        log.info("DIFF: timespan before limits: %d", realtimespan)
        if realtimespan < targettimespan/4: realtimespan = targettimespan/4
        if realtimespan > targettimespan*4: realtimespan = targettimespan*4
        log.info("DIFF: timespan after limits: %d", realtimespan)
        newtarget = (bits_to_target(self.block.bits)*realtimespan)/targettimespan
        if newtarget > bits_to_target(0x1d00ffff):
            newtarget = bits_to_target(0x1d00ffff)
        bits = target_to_bits(newtarget)
        log.info("DIFF: next bits: %s", hex(bits))

        return bits