URI: 
       tMerge pull request #1558 from fanatid/spv - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 4112e2c3fac36d5384e5a9734d8f808acb0acb78
   DIR parent 4195001aed9a5a307cbd83b19f9e66af390643b6
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Fri, 11 Dec 2015 10:09:11 +0100
       
       Merge pull request #1558 from fanatid/spv
       
       Improve get_target
       Diffstat:
         M lib/blockchain.py                   |      49 ++++++++++++++++---------------
       
       1 file changed, 25 insertions(+), 24 deletions(-)
       ---
   DIR diff --git a/lib/blockchain.py b/lib/blockchain.py
       t@@ -50,7 +50,11 @@ class Blockchain(util.PrintError):
                        self.print_error("prev hash mismatch: %s vs %s"
                                         % (prev_hash, header.get('prev_block_hash')))
                        return False
       -            bits, target = self.get_target(height/2016, chain)
       +            try:
       +                bits, target = self.get_target(height/2016, chain)
       +            except AssertionError as e:
       +                self.print_error("target calculation error: %s" % (str(e)))
       +                return False
                    if bits != header.get('bits'):
                        self.print_error("bits mismatch: %s vs %s"
                                         % (bits, header.get('bits')))
       t@@ -88,7 +92,7 @@ class Blockchain(util.PrintError):
                    _hash = self.hash_header(header)
                    assert previous_hash == header.get('prev_block_hash')
                    assert bits == header.get('bits')
       -            assert int('0x'+_hash,16) < target
       +            assert int('0x'+_hash,16) <= target
        
                    previous_header = header
                    previous_hash = _hash
       t@@ -190,36 +194,33 @@ class Blockchain(util.PrintError):
                        if h.get('block_height') == index*2016-1:
                            last = h
        
       +        # bits to target
       +        bits = last.get('bits')
       +        bitsN = (bits >> 24) & 0xff
       +        assert bitsN >= 0x03 and bitsN <= 0x1d, "First part of bits should be in [0x03, 0x1d]"
       +        bitsBase = bits & 0xffffff
       +        assert bitsN >= 0x8000 and bitsN <= 0x7fffff, "Second part of bits should be in [0x8000, 0x7fffff]"
       +        target = bitsBase << (8*(bitsN-3))
       +
       +        # new target
                nActualTimespan = last.get('timestamp') - first.get('timestamp')
                nTargetTimespan = 14*24*60*60
                nActualTimespan = max(nActualTimespan, nTargetTimespan/4)
                nActualTimespan = min(nActualTimespan, nTargetTimespan*4)
       +        new_target = min(max_target, (target * nActualTimespan)/nTargetTimespan)
        
       -        bits = last.get('bits')
       -        # 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, (target * nActualTimespan)/nTargetTimespan )
       -
       -        # convert it to bits
       -        c = ("%064X"%new_target)[2:]
       -        i = 31
       -        while c[0:2]=="00":
       +        # convert new target to bits
       +        c = ("%064x" % new_target)[2:]
       +        while c[:2] == '00' and len(c) > 6:
                    c = c[2:]
       -            i -= 1
        
       -        c = int('0x'+c[0:6],16)
       -        if c >= 0x800000:
       -            c /= 256
       -            i += 1
       +        bitsN, bitsBase = len(c)/2, int('0x'+c[:6], 16)
       +        if bitsBase >= 0x800000:
       +            bitsN += 1
       +            bitsBase >>= 8
        
       -        new_bits = c + MM * i
       -        return new_bits, new_target
       +        new_bits = bitsN << 24 | bitsBase
       +        return new_bits, bitsBase << (8*(bitsN-3))
        
            def connect_header(self, chain, header):
                '''Builds a header chain until it connects.  Returns True if it has