pooler/electrum-ltc

Error in an attempt to update checkpoints.json

Closed this issue · 2 comments

n3v1l commented

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

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

network.export_checkpoints("checkpoints.json")
n3v1l commented

Oh yeah! that solved this. Thanks!