pooler / electrum-ltc

Electrum-LTC Litecoin wallet
https://electrum-ltc.org
MIT License
200 stars 102 forks source link

Error in an attempt to update checkpoints.json #286

Closed n3v1l closed 2 years ago

n3v1l commented 2 years ago

hi @all . I have tried to build everything from the source (just run ./run:_electrum on my linux machine), but I wanted to recreate the checkpoints.json with an updated one, so it takes a little less time the first connection to the blockchain, but I didn't find a way to do it. I have found a couple of script, but none of them really works, when I copy the created checkpoints.json to replace the original one , I ended up with the error:

File "electrum-ltc/electrum_ltc/interface.py", line 834, in _search_headers_binary raise Exception('unexpected bad header during binary: {}'.format(bad_header)) Exception: unexpected bad header during binary: {'version': 536870912, 'prev_block_hash': '6264761abb597909a78af9c89d12aa374d4a680ece076b5e184b1a053daa2547', 'merkle_root': '19c390175d67f2087d8804a31253ecac14c8a787b23feacd2f2e70409f80e5e6', 'timestamp': 1647011395, 'bits': 436286156, 'nonce': 1024863879, 'block_height': 2225664}

I tried to use the function bits_to_target within a Pyhon script that I slightly modified (credits to https://github.com/exoeconomy/EXOS-Electrum/blob/master/contrib/get_checkpoint_array.py) to add the same bits_to_target function and timestamp of blockchain.py:

#!/usr/bin/env python3
import json
import sys 
import base64
import urllib.request

if len(sys.argv) < 3:
    print('Arguments: <rpc_username> <rpc_password> [<rpc_port>]')
    sys.exit(1)

# From electrum.
def bits_to_target(bits: int) -> int:
       # arith_uint256::SetCompact in Bitcoin Core
        if not (0 <= bits < (1 << 32)):
            raise Exception(f"bits should be uint32. got {bits!r}")
        bitsN = (bits >> 24) & 0xff
        bitsBase = bits & 0x7fffff
        if bitsN <= 3:
            target = bitsBase >> (8 * (3-bitsN))
        else:
            target = bitsBase << (8 * (bitsN-3))
        if target != 0 and bits & 0x800000 != 0:
            # Bit number 24 (0x800000) represents the sign of N
            raise Exception("target cannot be negative")
        if (target != 0 and
                (bitsN > 34 or
                 (bitsN > 33 and bitsBase > 0xff) or
                 (bitsN > 32 and bitsBase > 0xffff))):
            raise Exception("target has overflown")
        return target

def rpc(method, params):
    data = {
        "jsonrpc": "1.0",
        "id":"1",
        "method": method,
        "params": params
    }

    data_json = json.dumps(data)
    username = sys.argv[1]
    password = sys.argv[2]
    port = 8332
    if len(sys.argv) > 3:
        port = sys.argv[3]
    url = "http://127.0.0.1:{}/".format(port)
    req = urllib.request.Request(url, data_json.encode("utf-8"), {'content-type': 'application/json'})

    base64string = base64.encodestring(('%s:%s' % (username, password)).encode()).decode().replace('\n', '')
    req.add_header("Authorization", "Basic %s" % base64string)

    response_stream = urllib.request.urlopen(req)
    json_response = response_stream.read()

    return json.loads(json_response)

# Electrum checkpoints are blocks 2015, 2015 + 2016, 2015 + 2016*2, ...
i = 2015
INTERVAL = 2016

checkpoints = []
block_count = int(rpc('getblockcount', [])['result'])
print(('Blocks: {}'.format(block_count)))
while True:
    h = rpc('getblockhash', [i])['result']
    block = rpc('getblock', [h])['result']
    print("Bloque bits a transformar" + block['bits'])
    checkpoints.append([
        block['hash'],
        bits_to_target(int(block['bits'], 16)),
        block['time']
    ])

    i += INTERVAL
    if i > block_count:
        print('Done.')
        break

with open('checkpoints_output.json', 'w+') as f:
    f.write(json.dumps(checkpoints, indent=4, separators=(',', ':')))

But it doesn't give me the same checkpoints.json result. Can you point me in the right direction?

Thanks in advance

pooler commented 2 years ago

If you simply want to recreate the file, you can run this in the console:

network.export_checkpoints("checkpoints.json")
n3v1l commented 2 years ago

Oh yeah! that solved this. Thanks!