summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMagnus Ahltorp <map@kth.se>2014-11-18 17:06:53 +0100
committerMagnus Ahltorp <map@kth.se>2014-11-19 05:03:19 +0100
commit72fdb2fb8870f49cb066eca754e87e7b7e5d82d9 (patch)
treef880bf106a4300a739ce41b04f3d213ab9a858b5 /src
parent41412486d1b128057e453ac94c675a83a2f3e1b4 (diff)
Make ht load tree and verify root hash before updating tree size
Diffstat (limited to 'src')
-rw-r--r--src/frontend.erl13
-rw-r--r--src/ht.erl15
2 files changed, 24 insertions, 4 deletions
diff --git a/src/frontend.erl b/src/frontend.erl
index 9c69517..6fc2fd5 100644
--- a/src/frontend.erl
+++ b/src/frontend.erl
@@ -41,6 +41,7 @@ request(post, "ct/frontend/sendsth", Input) ->
{struct, PropList} ->
OldSize = db:size(),
Treesize = proplists:get_value(<<"tree_size">>, PropList),
+ RootHash = base64:decode(proplists:get_value(<<"sha256_root_hash">>, PropList)),
Indexsize = db:indexsize(),
if
@@ -59,9 +60,15 @@ request(post, "ct/frontend/sendsth", Input) ->
case Errors of
[] ->
- ok = db:set_treesize(Treesize),
- ht:reset_tree([db:size() - 1]),
- success({[{result, <<"ok">>}]});
+ ht:load_tree(Treesize - 1),
+ OwnRootHash = ht:root(Treesize - 1),
+ case OwnRootHash of
+ RootHash ->
+ ok = db:set_treesize(Treesize),
+ success({[{result, <<"ok">>}]});
+ _ ->
+ html("Root hash not the same", hex:bin_to_hexstr(OwnRootHash))
+ end;
_ ->
html("Database not complete", Errors)
end
diff --git a/src/ht.erl b/src/ht.erl
index b4c7401..4b08e34 100644
--- a/src/ht.erl
+++ b/src/ht.erl
@@ -28,7 +28,7 @@
-module(ht).
-behaviour(gen_server).
--export([reset_tree/1, size/0, leaf_hash/1]).
+-export([reset_tree/1, load_tree/1, size/0, leaf_hash/1]).
-export([add/1, root/0, root/1, path/2, consistency/2]).
-export([start_link/0, start_link/1, stop/0]).
-export([init/1, handle_call/3, terminate/2, handle_cast/2, handle_info/2,
@@ -53,6 +53,8 @@ start_link(NEntries) ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [NEntries], []).
reset_tree(Arg) ->
call(?MODULE, {reset_tree, Arg}).
+load_tree(Version) ->
+ call(?MODULE, {load_tree, Version}).
stop() ->
call(?MODULE, stop).
size() ->
@@ -93,6 +95,9 @@ terminate(_Reason, _State) ->
handle_call({reset_tree, Arg}, _From, _State) ->
NewTree = new(Arg),
{reply, NewTree, NewTree};
+handle_call({load_tree, Version}, _From, State) ->
+ {Reply, NewTree} = read_new_entries(State, Version),
+ {reply, Reply, NewTree};
handle_call(stop, _From, State) ->
{stop, normal, stopped, State};
handle_call(size, _From, State) ->
@@ -256,6 +261,14 @@ first_left_node(Layer, Index, BAL) ->
add(Tree = #tree{version = V, store = Store}, Hash) ->
Tree#tree{version = V + 1, store = ts:add(Store, 0, Hash)}.
+read_new_entries(State, Version) when is_integer(Version) ->
+ NewEntries = db:get_by_indices(State#tree.version + 1, Version, {sorted, true}),
+ NewState = foldl(fun(Hash, Tree) ->
+ add(Tree, Hash)
+ end, State, [H || {_I, H, _E} <-
+ NewEntries]),
+ {ok, NewState}.
+
%% @doc Return a new tree.
-spec new(list()) -> tree().
new([]) ->