mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-11 23:58:18 +00:00
fee6799b12
0) Adjust BIP30 enforcement values 1) Reduce amount that peers can adjust our time to eliminate an attack vector. Thanks to coblee for this fix. 2) Zeitgeist2 patch - thanks to Lolcust and ArtForz. This fixes an issue where a 51% attack can change difficulty at will. Go back the full period unless it's the first retarget after genesis. 3) Avoid overflow in CalculateNextWorkRequired(). Thanks to pooler for the overflow fix. 4) Zeitgeist2 bool fshift bnNew.bits(). Thanks to romanornr for this path. 5) SegWit ContextualCheckBlockHeader adjustment and extra coverage. 6) Reject peer proto version below 70002. Thanks to wtogami for this patch. 7) Send final alert message to nodes warning about removal of the alert system. Thanks to coblee for this patch. 8) Adjust default settings for Litecoin.
158 lines
4.5 KiB
Python
Executable File
158 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# linearize-hashes.py: List blocks in a linear, no-fork version of the chain.
|
|
#
|
|
# Copyright (c) 2013-2017 The Bitcoin Core developers
|
|
# Distributed under the MIT software license, see the accompanying
|
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
#
|
|
|
|
from __future__ import print_function
|
|
try: # Python 3
|
|
import http.client as httplib
|
|
except ImportError: # Python 2
|
|
import httplib
|
|
import json
|
|
import re
|
|
import base64
|
|
import sys
|
|
import os
|
|
import os.path
|
|
|
|
settings = {}
|
|
|
|
##### Switch endian-ness #####
|
|
def hex_switchEndian(s):
|
|
""" Switches the endianness of a hex string (in pairs of hex chars) """
|
|
pairList = [s[i:i+2].encode() for i in range(0, len(s), 2)]
|
|
return b''.join(pairList[::-1]).decode()
|
|
|
|
class BitcoinRPC:
|
|
def __init__(self, host, port, username, password):
|
|
authpair = "%s:%s" % (username, password)
|
|
authpair = authpair.encode('utf-8')
|
|
self.authhdr = b"Basic " + base64.b64encode(authpair)
|
|
self.conn = httplib.HTTPConnection(host, port=port, timeout=30)
|
|
|
|
def execute(self, obj):
|
|
try:
|
|
self.conn.request('POST', '/', json.dumps(obj),
|
|
{ 'Authorization' : self.authhdr,
|
|
'Content-type' : 'application/json' })
|
|
except ConnectionRefusedError:
|
|
print('RPC connection refused. Check RPC settings and the server status.',
|
|
file=sys.stderr)
|
|
return None
|
|
|
|
resp = self.conn.getresponse()
|
|
if resp is None:
|
|
print("JSON-RPC: no response", file=sys.stderr)
|
|
return None
|
|
|
|
body = resp.read().decode('utf-8')
|
|
resp_obj = json.loads(body)
|
|
return resp_obj
|
|
|
|
@staticmethod
|
|
def build_request(idx, method, params):
|
|
obj = { 'version' : '1.1',
|
|
'method' : method,
|
|
'id' : idx }
|
|
if params is None:
|
|
obj['params'] = []
|
|
else:
|
|
obj['params'] = params
|
|
return obj
|
|
|
|
@staticmethod
|
|
def response_is_error(resp_obj):
|
|
return 'error' in resp_obj and resp_obj['error'] is not None
|
|
|
|
def get_block_hashes(settings, max_blocks_per_call=10000):
|
|
rpc = BitcoinRPC(settings['host'], settings['port'],
|
|
settings['rpcuser'], settings['rpcpassword'])
|
|
|
|
height = settings['min_height']
|
|
while height < settings['max_height']+1:
|
|
num_blocks = min(settings['max_height']+1-height, max_blocks_per_call)
|
|
batch = []
|
|
for x in range(num_blocks):
|
|
batch.append(rpc.build_request(x, 'getblockhash', [height + x]))
|
|
|
|
reply = rpc.execute(batch)
|
|
if reply is None:
|
|
print('Cannot continue. Program will halt.')
|
|
return None
|
|
|
|
for x,resp_obj in enumerate(reply):
|
|
if rpc.response_is_error(resp_obj):
|
|
print('JSON-RPC: error at height', height+x, ': ', resp_obj['error'], file=sys.stderr)
|
|
sys.exit(1)
|
|
assert(resp_obj['id'] == x) # assume replies are in-sequence
|
|
if settings['rev_hash_bytes'] == 'true':
|
|
resp_obj['result'] = hex_switchEndian(resp_obj['result'])
|
|
print(resp_obj['result'])
|
|
|
|
height += num_blocks
|
|
|
|
def get_rpc_cookie():
|
|
# Open the cookie file
|
|
with open(os.path.join(os.path.expanduser(settings['datadir']), '.cookie'), 'r') as f:
|
|
combined = f.readline()
|
|
combined_split = combined.split(":")
|
|
settings['rpcuser'] = combined_split[0]
|
|
settings['rpcpassword'] = combined_split[1]
|
|
|
|
if __name__ == '__main__':
|
|
if len(sys.argv) != 2:
|
|
print("Usage: linearize-hashes.py CONFIG-FILE")
|
|
sys.exit(1)
|
|
|
|
f = open(sys.argv[1])
|
|
for line in f:
|
|
# skip comment lines
|
|
m = re.search('^\s*#', line)
|
|
if m:
|
|
continue
|
|
|
|
# parse key=value lines
|
|
m = re.search('^(\w+)\s*=\s*(\S.*)$', line)
|
|
if m is None:
|
|
continue
|
|
settings[m.group(1)] = m.group(2)
|
|
f.close()
|
|
|
|
if 'host' not in settings:
|
|
settings['host'] = '127.0.0.1'
|
|
if 'port' not in settings:
|
|
settings['port'] = 9332
|
|
if 'min_height' not in settings:
|
|
settings['min_height'] = 0
|
|
if 'max_height' not in settings:
|
|
settings['max_height'] = 313000
|
|
if 'rev_hash_bytes' not in settings:
|
|
settings['rev_hash_bytes'] = 'false'
|
|
|
|
use_userpass = True
|
|
use_datadir = False
|
|
if 'rpcuser' not in settings or 'rpcpassword' not in settings:
|
|
use_userpass = False
|
|
if 'datadir' in settings and not use_userpass:
|
|
use_datadir = True
|
|
if not use_userpass and not use_datadir:
|
|
print("Missing datadir or username and/or password in cfg file", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
settings['port'] = int(settings['port'])
|
|
settings['min_height'] = int(settings['min_height'])
|
|
settings['max_height'] = int(settings['max_height'])
|
|
|
|
# Force hash byte format setting to be lowercase to make comparisons easier.
|
|
settings['rev_hash_bytes'] = settings['rev_hash_bytes'].lower()
|
|
|
|
# Get the rpc user and pass from the cookie if the datadir is set
|
|
if use_datadir:
|
|
get_rpc_cookie()
|
|
|
|
get_block_hashes(settings)
|