def get_target_from_timespans(self, bits, nActualTimespan, nTargetTimespan):

        # convert to bignum
        MM = 256*256*256
        a = bits%MM
        if a < 0x8000:
            a *= 256
        target = (a) * pow(2, 8 * (bits/MM - 3))

        # new target
        new_target = min( max_target, cdiv(target * nActualTimespan, nTargetTimespan) )

        # convert it to bits
        c = ("%064X"%new_target)[2:]
        i = 31
        while c[0:2]=="00":
            c = c[2:]
            i -= 1

        c = int('0x'+c[0:6],16)
        if c >= 0x800000:
            c /= 256
            i += 1

        new_bits = c + MM * i

        #print 'new target: ', hex(new_target)
        return new_bits, new_target
    def get_target_from_timespans(self, bits, nActualTimespan,
                                  nTargetTimespan):

        # convert to bignum
        MM = 256 * 256 * 256
        a = bits % MM
        if a < 0x8000:
            a *= 256
        target = (a) * pow(2, 8 * (bits / MM - 3))

        # new target
        new_target = min(max_target,
                         cdiv(target * nActualTimespan, nTargetTimespan))

        # convert it to bits
        c = ("%064X" % new_target)[2:]
        i = 31
        while c[0:2] == "00":
            c = c[2:]
            i -= 1

        c = int('0x' + c[0:6], 16)
        if c >= 0x800000:
            c /= 256
            i += 1

        new_bits = c + MM * i

        #print 'new target: ', hex(new_target)
        return new_bits, new_target
    def get_target(self, height, chain=None):
        if chain is None:
            chain = []  # Do not use mutables as default values!

        if height < 240: return 0x1e0ffff0, 0x00000FFFF0000000000000000000000000000000000000000000000000000000

        nTargetTimespan = 4*60*60 #dogecoin: every 4 hours
        nTargetTimespanNEW = 60 #dogecoin: every 1 minute

        nTargetSpacing = 60 #dogecoin: 1 minute
        nInterval = nTargetTimespan / nTargetSpacing #240

        retargetTimespan = nTargetTimespan
        retargetInterval = nInterval

        if height > digishield_start:
            retargetInterval =  nTargetTimespanNEW / nTargetSpacing #1
            retargetTimespan = nTargetTimespanNEW

        blockstogoback = retargetInterval - 1
        if (height != retargetInterval):
            blockstogoback = retargetInterval

        latest_retarget_height = (height / retargetInterval) * retargetInterval
        #print 'latest_retarget_height', latest_retarget_height
        last_height = latest_retarget_height - 1
        first_height = last_height - blockstogoback

        #print 'first height', first_height
        #print 'last height', last_height

        first = self.read_header(first_height)
        last = self.read_header(last_height)

        #print 'first'
        #print first
        #print 'last'
        #print last

        if first is None:
            for h in chain:
                if h.get('block_height') == first_height:
                    first = h

        if last is None:
            for h in chain:
                if h.get('block_height') == last_height:
                    last = h

        nActualTimespan = last.get('timestamp') - first.get('timestamp')
        nModulatedTimespan = nActualTimespan

        if height <= 5000:
            nModulatedTimespan = max(nModulatedTimespan, cdiv(nTargetTimespan, 16))
            nModulatedTimespan = min(nModulatedTimespan, nTargetTimespan*4)
        elif height <= 10000:
            nModulatedTimespan = max(nModulatedTimespan, cdiv(nTargetTimespan, 8))
            nModulatedTimespan = min(nModulatedTimespan, nTargetTimespan*4)
        elif height <= digishield_start:
            nModulatedTimespan = max(nModulatedTimespan, cdiv(nTargetTimespan, 4))
            nModulatedTimespan = min(nModulatedTimespan, nTargetTimespan*4)
        # digishield
        # https://github.com/dogecoin/dogecoin/blob/master/src/main.cpp#L1354
        else:
            nModulatedTimespan = retargetTimespan + cdiv(nModulatedTimespan - retargetTimespan, 8)
            nModulatedTimespan = max(nModulatedTimespan, retargetTimespan - cdiv(retargetTimespan, 4))
            nModulatedTimespan = min(nModulatedTimespan, retargetTimespan + cdiv(retargetTimespan, 2))

        bits = last.get('bits')

        #print 'before', hex(bits)
        #print 'nActualTimespan', nActualTimespan
        #print 'nTargetTimespan', nTargetTimespan
        #print 'retargetTimespan', retargetTimespan
        #print 'nModulatedTimespan', nModulatedTimespan

        return self.get_target_from_timespans(bits, nModulatedTimespan, retargetTimespan)
    def get_target(self, height, chain=None):
        if chain is None:
            chain = []  # Do not use mutables as default values!

        if height < 240:
            return 0x1e0ffff0, 0x00000FFFF0000000000000000000000000000000000000000000000000000000

        nTargetTimespan = 4 * 60 * 60  #dogecoin: every 4 hours
        nTargetTimespanNEW = 60  #dogecoin: every 1 minute

        nTargetSpacing = 60  #dogecoin: 1 minute
        nInterval = nTargetTimespan / nTargetSpacing  #240

        retargetTimespan = nTargetTimespan
        retargetInterval = nInterval

        if height > digishield_start:
            retargetInterval = nTargetTimespanNEW / nTargetSpacing  #1
            retargetTimespan = nTargetTimespanNEW

        blockstogoback = retargetInterval - 1
        if (height != retargetInterval):
            blockstogoback = retargetInterval

        latest_retarget_height = (height / retargetInterval) * retargetInterval
        #print 'latest_retarget_height', latest_retarget_height
        last_height = latest_retarget_height - 1
        first_height = last_height - blockstogoback

        #print 'first height', first_height
        #print 'last height', last_height

        first = self.read_header(first_height)
        last = self.read_header(last_height)

        #print 'first'
        #print first
        #print 'last'
        #print last

        if first is None:
            for h in chain:
                if h.get('block_height') == first_height:
                    first = h

        if last is None:
            for h in chain:
                if h.get('block_height') == last_height:
                    last = h

        nActualTimespan = last.get('timestamp') - first.get('timestamp')
        nModulatedTimespan = nActualTimespan

        if height <= 5000:
            nModulatedTimespan = max(nModulatedTimespan,
                                     cdiv(nTargetTimespan, 16))
            nModulatedTimespan = min(nModulatedTimespan, nTargetTimespan * 4)
        elif height <= 10000:
            nModulatedTimespan = max(nModulatedTimespan,
                                     cdiv(nTargetTimespan, 8))
            nModulatedTimespan = min(nModulatedTimespan, nTargetTimespan * 4)
        elif height <= digishield_start:
            nModulatedTimespan = max(nModulatedTimespan,
                                     cdiv(nTargetTimespan, 4))
            nModulatedTimespan = min(nModulatedTimespan, nTargetTimespan * 4)
        # digishield
        # https://github.com/dogecoin/dogecoin/blob/master/src/main.cpp#L1354
        else:
            nModulatedTimespan = retargetTimespan + cdiv(
                nModulatedTimespan - retargetTimespan, 8)
            nModulatedTimespan = max(
                nModulatedTimespan,
                retargetTimespan - cdiv(retargetTimespan, 4))
            nModulatedTimespan = min(
                nModulatedTimespan,
                retargetTimespan + cdiv(retargetTimespan, 2))

        bits = last.get('bits')

        #print 'before', hex(bits)
        #print 'nActualTimespan', nActualTimespan
        #print 'nTargetTimespan', nTargetTimespan
        #print 'retargetTimespan', retargetTimespan
        #print 'nModulatedTimespan', nModulatedTimespan

        return self.get_target_from_timespans(bits, nModulatedTimespan,
                                              retargetTimespan)