From 4325a43d3d1476cc601b631620df89340ec4c7e2 Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Mon, 20 Oct 2014 14:33:41 +0200 Subject: Added external merging support --- tools/merge.py | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100755 tools/merge.py (limited to 'tools/merge.py') diff --git a/tools/merge.py b/tools/merge.py new file mode 100755 index 0000000..7120d04 --- /dev/null +++ b/tools/merge.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2014 Kungliga Tekniska Högskolan +# (KTH Royal Institute of Technology, Stockholm, Sweden). +# See LICENSE for licensing information. + +import json +import base64 +import urllib +import urllib2 +import sys + +frontendnodes = ["https://127.0.0.1:8080/"] +storagenodes = ["https://127.0.0.1:8081/"] + +chainsdir = "../rel/mergedb/chains" +logorderfile = "../rel/mergedb/logorder" + +def parselogrow(row): + return base64.b16decode(row) + +def get_logorder(): + f = open(logorderfile, "r") + return [parselogrow(row.rstrip()) for row in f] + +def write_chain(key, value): + f = open(chainsdir + "/" + base64.b16encode(key), "w") + f.write(value) + f.close() + +def read_chain(key): + f = open(chainsdir + "/" + base64.b16encode(key), "r") + value = f.read() + f.close() + return value + +def add_to_logorder(key): + f = open(logorderfile, "a") + f.write(base64.b16encode(key) + "\n") + f.close() + +def get_new_entries(baseurl): + try: + result = urllib2.urlopen(baseurl + "ct/storage/fetchnewentries").read() + parsed_result = json.loads(result) + if parsed_result.get(u"result") == u"ok": + return parsed_result[u"entries"] + print "ERROR: fetchnewentries", parsed_result + sys.exit(1) + except urllib2.HTTPError, e: + print "ERROR: fetchnewentries", e.read() + sys.exit(1) + +def get_curpos(baseurl): + try: + result = urllib2.urlopen(baseurl + "ct/frontend/currentposition").read() + parsed_result = json.loads(result) + if parsed_result.get(u"result") == u"ok": + return parsed_result[u"position"] + print "ERROR: currentposition", parsed_result + sys.exit(1) + except urllib2.HTTPError, e: + print "ERROR: currentposition", e.read() + sys.exit(1) + +def sendlog(baseurl, submission): + try: + result = urllib2.urlopen(baseurl + "ct/frontend/sendlog", + json.dumps(submission)).read() + return json.loads(result) + except urllib2.HTTPError, e: + print "ERROR: sendlog", e.read() + sys.exit(1) + except ValueError, e: + print "==== FAILED REQUEST ====" + print submission + print "======= RESPONSE =======" + print result + print "========================" + raise e + +def sendsth(baseurl, submission): + try: + result = urllib2.urlopen(baseurl + "ct/frontend/sendsth", + json.dumps(submission)).read() + return json.loads(result) + except urllib2.HTTPError, e: + print "ERROR: sendsth", e.read() + sys.exit(1) + except ValueError, e: + print "==== FAILED REQUEST ====" + print submission + print "======= RESPONSE =======" + print result + print "========================" + raise e + +def get_missingentries(baseurl): + try: + result = urllib2.urlopen(baseurl + "ct/frontend/missingentries").read() + parsed_result = json.loads(result) + if parsed_result.get(u"result") == u"ok": + return parsed_result[u"entries"] + print "ERROR: missingentries", parsed_result + sys.exit(1) + except urllib2.HTTPError, e: + print "ERROR: missingentries", e.read() + sys.exit(1) + + +logorder = get_logorder() +certsinlog = set(logorder) + +new_entries = [entry for storagenode in storagenodes for entry in get_new_entries(storagenode)] + +for new_entry in new_entries: + hash = base64.b64decode(new_entry["hash"]) + entry = base64.b64decode(new_entry["entry"]) + if hash not in certsinlog: + write_chain(hash, entry) + add_to_logorder(hash) + logorder.append(hash) + certsinlog.add(hash) + print "added", base64.b16encode(hash) + +for frontendnode in frontendnodes: + curpos = get_curpos(frontendnode) + entries = [base64.b64encode(entry) for entry in logorder[curpos:]] + sendlog(frontendnode, {"start": curpos, "hashes": entries}) + missingentries = get_missingentries(frontendnode) + print "missing entries:", missingentries + # XXX: no test case for missing entries yet, waiting to implement + sendsth(frontendnode, {"tree_size": len(logorder)}) -- cgit v1.1