Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better staking, linearize, Qt5 support #1

Merged
merged 1 commit into from Aug 9, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 9 additions & 3 deletions SSD.pro
Expand Up @@ -22,11 +22,17 @@ VERSION = 2.4.0.0
INCLUDEPATH += src src/json src/qt src/tor
INCLUDEPATH += src/tor/adapter src/tor/common src/tor/ext
INCLUDEPATH += src/tor/ext/curve25519_donna src/tor/or
QT += core gui network webkit
QT += core gui network
CONFIG += no_include_pwd
CONFIG += thread+
CONFIG += qt

greaterThan(QT_MAJOR_VERSION, 4): QT += webkit widgets
greaterThan(QT_MAJOR_VERSION, 4): {
QT += widgets webkit webkitwidgets
message("Qt 5")
} else {
message("Qt 4")
}

!macx:CONFIG += static

Expand Down Expand Up @@ -658,7 +664,7 @@ macx|win32 {
# LIBS += /usr/local/boost/stage/lib/libboost_thread.a
# LIBS += /usr/local/boost/stage/lib/libboost_program_options.a
# custom linux for static
LIBS += /usr/lib/x86_64-linux-gnu/libdb_cxx-5.3.a
LIBS += /usr/local/BerkeleyDB.4.8/lib/libdb_cxx-4.8.a
LIBS += /usr/lib/libcryptopp.a
}

Expand Down
33 changes: 33 additions & 0 deletions contrib/linearize/README.md
@@ -0,0 +1,33 @@
# Linearize
Construct a linear, no-fork, best version of the blockchain.

## Step 1: Download hash list

$ ./linearize-hashes.py linearize.cfg > hashlist.txt

Required configuration file settings for linearize-hashes:
* RPC: rpcuser, rpcpassword

Optional config file setting for linearize-hashes:
* RPC: host, port
* Block chain: min_height, max_height

## Step 2: Copy local block data

$ ./linearize-data.py linearize.cfg

Required configuration file settings:
* "input": bitcoind blocks/ directory containing blkNNNNN.dat
* "hashlist": text file containing list of block hashes, linearized-hashes.py
output.
* "output_file": bootstrap.dat
or
* "output": output directory for linearized blocks/blkNNNNN.dat output

Optional config file setting for linearize-data:
* "netmagic": network magic number
* "max_out_sz": maximum output file size (default 1000*1000*1000)
* "split_timestamp": Split files when a new month is first seen, in addition to
reaching a maximum file size.
* "file_timestamp": Set each file's last-modified time to that of the
most recent block in that file.
239 changes: 239 additions & 0 deletions contrib/linearize/linearize-data.py
@@ -0,0 +1,239 @@
#!/usr/bin/python
#
# linearize-data.py: Construct a linear, no-fork version of the chain.
#
# Copyright (c) 2013 The Bitcoin developers
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#

import json
import struct
import re
import os
import base64
import httplib
import sys
import hashlib
import datetime
import time

settings = {}


def uint32(x):
return x & 0xffffffffL

def bytereverse(x):
return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) |
(((x) >> 8) & 0x0000ff00) | ((x) >> 24) ))

def bufreverse(in_buf):
out_words = []
for i in range(0, len(in_buf), 4):
word = struct.unpack('@I', in_buf[i:i+4])[0]
out_words.append(struct.pack('@I', bytereverse(word)))
return ''.join(out_words)

def wordreverse(in_buf):
out_words = []
for i in range(0, len(in_buf), 4):
out_words.append(in_buf[i:i+4])
out_words.reverse()
return ''.join(out_words)

def calc_hdr_hash(blk_hdr):
hash1 = hashlib.sha256()
hash1.update(blk_hdr)
hash1_o = hash1.digest()

hash2 = hashlib.sha256()
hash2.update(hash1_o)
hash2_o = hash2.digest()
return hash2_o

def calc_hash_str(blk_hdr):
hash = calc_hdr_hash(blk_hdr)
hash = bufreverse(hash)
hash = wordreverse(hash)
hash_str = hash.encode('hex')
return hash_str

def get_blk_dt(blk_hdr):
members = struct.unpack("<I", blk_hdr[68:68+4])
nTime = members[0]
dt = datetime.datetime.fromtimestamp(nTime)
dt_ym = datetime.datetime(dt.year, dt.month, 1)
return (dt_ym, nTime)

def get_block_hashes(settings):
blkindex = []
f = open(settings['hashlist'], "r")
for line in f:
line = line.rstrip()
blkindex.append(line)

print("Read " + str(len(blkindex)) + " hashes")

return blkindex

def mkblockset(blkindex):
blkmap = {}
for hash in blkindex:
blkmap[hash] = True
return blkmap

def copydata(settings, blkindex, blkset):
inFn = 1
inF = None
outFn = 0
outsz = 0
outF = None
outFname = None
blkCount = 0

lastDate = datetime.datetime(2000, 1, 1)
highTS = 1408893517 - 315360000
timestampSplit = False
fileOutput = True
setFileTime = False
maxOutSz = settings['max_out_sz']
if 'output' in settings:
fileOutput = False
if settings['file_timestamp'] != 0:
setFileTime = True
if settings['split_timestamp'] != 0:
timestampSplit = True

while True:
if not inF:
fname = "%s/blk%04d.dat" % (settings['input'], inFn)
print("Input file" + fname)
try:
inF = open(fname, "rb")
except IOError:
print "Done"
return

inhdr = inF.read(8)
if (not inhdr or (inhdr[0] == "\0")):
inF.close()
inF = None
inFn = inFn + 1
continue

inMagic = inhdr[:4]
if (inMagic != settings['netmagic']):
print("Invalid magic:" + inMagic)
return
inLenLE = inhdr[4:]
su = struct.unpack("<I", inLenLE)
inLen = su[0]
rawblock = inF.read(inLen)
blk_hdr = rawblock[:80]

hash_str = 0
hash_str = calc_hash_str(blk_hdr)

if not hash_str in blkset:
print("Skipping unknown block " + hash_str)
continue

if blkindex[blkCount] != hash_str:
print("Out of order block.")
print("Expected " + blkindex[blkCount])
print("Got " + hash_str)
print("Use the partial bootstrap.dat and then try to sync from net.")
sys.exit(1)

if not fileOutput and ((outsz + inLen) > maxOutSz):
outF.close()
if setFileTime:
os.utime(outFname, (int(time.time()), highTS))
outF = None
outFname = None
outFn = outFn + 1
outsz = 0

(blkDate, blkTS) = get_blk_dt(blk_hdr)
if timestampSplit and (blkDate > lastDate):
print("New month " + blkDate.strftime("%Y-%m") + " @ " + hash_str)
lastDate = blkDate
if outF:
outF.close()
if setFileTime:
os.utime(outFname, (int(time.time()), highTS))
outF = None
outFname = None
outFn = outFn + 1
outsz = 0

if not outF:
if fileOutput:
outFname = settings['output_file']
else:
outFname = "%s/blk%05d.dat" % (settings['output'], outFn)
print("Output file" + outFname)
outF = open(outFname, "wb")

outF.write(inhdr)
outF.write(rawblock)
outsz = outsz + inLen + 8

blkCount = blkCount + 1
if blkTS > highTS:
highTS = blkTS

if (blkCount % 1000) == 0:
print("Wrote " + str(blkCount) + " blocks")

if __name__ == '__main__':
if len(sys.argv) != 2:
print "Usage: linearize-data.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 'netmagic' not in settings:
settings['netmagic'] = '70352205'
if 'input' not in settings:
settings['input'] = 'input'
if 'hashlist' not in settings:
settings['hashlist'] = 'hashlist.txt'
if 'file_timestamp' not in settings:
settings['file_timestamp'] = 0
if 'split_timestamp' not in settings:
settings['split_timestamp'] = 0
if 'max_out_sz' not in settings:
settings['max_out_sz'] = 1000L * 1000 * 1000

settings['max_out_sz'] = long(settings['max_out_sz'])
settings['split_timestamp'] = int(settings['split_timestamp'])
settings['file_timestamp'] = int(settings['file_timestamp'])
settings['netmagic'] = settings['netmagic'].decode('hex')

if 'output_file' not in settings and 'output' not in settings:
print("Missing output file / directory")
sys.exit(1)

blkindex = get_block_hashes(settings)
blkset = mkblockset(blkindex)

if not "4c9cbed9e61fab42ef0433a821cf5de12f9d53a1f8481a0a85383f9668863973" in blkset:
print("not found")
else:
copydata(settings, blkindex, blkset)